From b0ab693c3805009aa5fe1065af71826cb9bec7d2 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 27 Jul 2023 03:43:05 +0000
Subject: [PATCH 001/111] load en translations in parallel
---
config/context_processors.py | 9 +++++++-
mathesar/templates/mathesar/index.html | 32 ++++++++++++++++++++++----
mathesar/utils/frontend.py | 15 +++++++++++-
mathesar_ui/src/App.svelte | 29 ++++++++++++++---------
mathesar_ui/src/i18n/i18n-load.ts | 8 +++++++
5 files changed, 75 insertions(+), 18 deletions(-)
diff --git a/config/context_processors.py b/config/context_processors.py
index da5e98a752..800fbcc31d 100644
--- a/config/context_processors.py
+++ b/config/context_processors.py
@@ -4,9 +4,16 @@
def frontend_settings(request):
+ """
+ Hard coding this for now
+ but will be taken from users model
+ and cookies later on
+ """
+ preferred_language = 'en'
frontend_settings = {
'development_mode': settings.MATHESAR_MODE == 'DEVELOPMENT',
- 'manifest_data': get_manifest_data(),
+ 'manifest_data': get_manifest_data(preferred_language),
+ 'preferred_language': preferred_language,
'live_demo_mode': getattr(settings, 'MATHESAR_LIVE_DEMO', False),
'live_demo_username': getattr(settings, 'MATHESAR_LIVE_DEMO_USERNAME', None),
'live_demo_password': getattr(settings, 'MATHESAR_LIVE_DEMO_PASSWORD', None),
diff --git a/mathesar/templates/mathesar/index.html b/mathesar/templates/mathesar/index.html
index e26130095d..2d4e616ef6 100644
--- a/mathesar/templates/mathesar/index.html
+++ b/mathesar/templates/mathesar/index.html
@@ -4,9 +4,11 @@
{% block title %}Home{% endblock %}
{% block styles %}
- {% if not development_mode %} {% for css_file in manifest_data.module_css %}
-
- {% endfor %} {% endif %}
+ {% if not development_mode %}
+ {% for css_file in manifest_data.module_css %}
+
+ {% endfor %}
+ {% endif %}
{% endblock %}
{% block scripts %}
@@ -17,6 +19,17 @@
{% endfor %}
{% endif %}
+
+
{% if development_mode %}
@@ -52,11 +65,20 @@
>
+
{% endif %}
diff --git a/mathesar/utils/frontend.py b/mathesar/utils/frontend.py
index 428017f7f0..78d7f4433c 100644
--- a/mathesar/utils/frontend.py
+++ b/mathesar/utils/frontend.py
@@ -4,7 +4,7 @@
from django.core.cache import cache
-def get_manifest_data():
+def get_manifest_data(preferred_language):
# We don't need the manifest data for local development.
if settings.MATHESAR_MODE == 'DEVELOPMENT':
return {}
@@ -18,14 +18,27 @@ def get_manifest_data():
with open(settings.MATHESAR_MANIFEST_LOCATION, 'r') as manifest_file:
raw_data = json.loads(manifest_file.read())
+ translations_file_path = get_translations_file_path(preferred_language)
+
module_data = raw_data['src/main.ts']
manifest_data['module_css'] = [filename for filename in module_data['css']]
manifest_data['module_js'] = module_data['file']
+ # Purposefully letting it fail if the translations file for that lang is not in the bundle
+ manifest_data['module_translations_file'] = raw_data[translations_file_path["module"]]["file"]
+
legacy_data = raw_data['src/main-legacy.ts']
manifest_data['legacy_polyfill_js'] = raw_data['vite/legacy-polyfills-legacy']['file']
manifest_data['legacy_js'] = legacy_data['file']
+ manifest_data['legacy_translations_file'] = raw_data[translations_file_path["legacy"]]["file"]
# Cache data for 1 hour
cache.set('manifest_data', manifest_data, 60 * 60)
return manifest_data
+
+
+def get_translations_file_path(preferred_language):
+ return {
+ "module": f'src/i18n/{preferred_language}/index.ts',
+ "legacy": f'src/i18n/{preferred_language}/index-legacy.ts'
+ }
diff --git a/mathesar_ui/src/App.svelte b/mathesar_ui/src/App.svelte
index 398725674e..1c7fb53f6e 100644
--- a/mathesar_ui/src/App.svelte
+++ b/mathesar_ui/src/App.svelte
@@ -19,21 +19,28 @@
import { modal } from './stores/modal';
import { setReleasesStoreInContext } from './stores/releases';
import ModalRecordSelector from './systems/record-selector/ModalRecordSelector.svelte';
- import { loadLocaleAsync } from './i18n/i18n-load';
import { setLocale } from './i18n/i18n-svelte';
+ import type { Locales } from './i18n/i18n-types';
+ import { loadTranslationsIntoMemory } from './i18n/i18n-load';
- /**
- * Later the translations file will be loaded
- * in parallel to the FE's first chunk
- */
let isTranslationsLoaded = false;
- (() => {
- void loadLocaleAsync('en').then(() => {
- setLocale('en');
+ const checkTranslationsInterval = setInterval(() => {
+ // eslint-disable-next-line prefer-destructuring
+ const translations:
+ | { lang: Locales; translationStrings: string }
+ | undefined =
+ // @ts-expect-error added by index.html
+ window.translations;
+ if (translations) {
+ loadTranslationsIntoMemory(
+ translations.lang,
+ JSON.parse(translations.translationStrings),
+ );
+ setLocale(translations.lang);
isTranslationsLoaded = true;
- return true;
- });
- })();
+ clearInterval(checkTranslationsInterval);
+ }
+ }, 100);
const commonData = preloadCommonData();
if (commonData?.user) {
diff --git a/mathesar_ui/src/i18n/i18n-load.ts b/mathesar_ui/src/i18n/i18n-load.ts
index 02f828295e..6e0aabee3b 100644
--- a/mathesar_ui/src/i18n/i18n-load.ts
+++ b/mathesar_ui/src/i18n/i18n-load.ts
@@ -30,3 +30,11 @@ export async function loadLocaleAsync(locale: Locales): Promise {
updateTranslationsDictionary(locale, await importLocaleAsync(locale));
loadFormatters(locale);
}
+
+export function loadTranslationsIntoMemory(
+ locale: Locales,
+ translations: Translations,
+) {
+ updateTranslationsDictionary(locale, translations);
+ loadFormatters(locale);
+}
From b1ceaa9ea4c07584e373e4bf394b1888ad9a0cc9 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 27 Jul 2023 09:17:21 +0000
Subject: [PATCH 002/111] BE - save users lang in the db
---
config/context_processors.py | 18 ++++++++++++------
mathesar/api/ui/serializers/users.py | 1 +
.../migrations/0004_user_preferred_language.py | 18 ++++++++++++++++++
mathesar/models/users.py | 1 +
mathesar/views.py | 1 +
5 files changed, 33 insertions(+), 6 deletions(-)
create mode 100644 mathesar/migrations/0004_user_preferred_language.py
diff --git a/config/context_processors.py b/config/context_processors.py
index 800fbcc31d..1828e543bb 100644
--- a/config/context_processors.py
+++ b/config/context_processors.py
@@ -4,12 +4,7 @@
def frontend_settings(request):
- """
- Hard coding this for now
- but will be taken from users model
- and cookies later on
- """
- preferred_language = 'en'
+ preferred_language = get_user_preferred_language_from_request(request)
frontend_settings = {
'development_mode': settings.MATHESAR_MODE == 'DEVELOPMENT',
'manifest_data': get_manifest_data(preferred_language),
@@ -22,3 +17,14 @@ def frontend_settings(request):
if frontend_settings['development_mode'] is True:
frontend_settings['client_dev_url'] = settings.MATHESAR_CLIENT_DEV_URL
return frontend_settings
+
+
+def get_user_preferred_language_from_request(request):
+ # https://docs.djangoproject.com/en/4.2/topics/i18n/translation/#how-django-discovers-language-preference
+ # This automatically fallbacks to en because of https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-LANGUAGE_CODE
+ lang_from_locale_middleware = request.LANGUAGE_CODE
+
+ if request.user.is_authenticated:
+ return request.user.preferred_language or lang_from_locale_middleware
+ else:
+ return lang_from_locale_middleware
diff --git a/mathesar/api/ui/serializers/users.py b/mathesar/api/ui/serializers/users.py
index 26fafd0cde..78b657cb97 100644
--- a/mathesar/api/ui/serializers/users.py
+++ b/mathesar/api/ui/serializers/users.py
@@ -40,6 +40,7 @@ class Meta:
'is_superuser',
'database_roles',
'schema_roles',
+ 'preferred_language'
]
extra_kwargs = {
'password': {'write_only': True},
diff --git a/mathesar/migrations/0004_user_preferred_language.py b/mathesar/migrations/0004_user_preferred_language.py
new file mode 100644
index 0000000000..be05706c91
--- /dev/null
+++ b/mathesar/migrations/0004_user_preferred_language.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.14 on 2023-07-27 09:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mathesar', '0003_datafile_max_level'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='preferred_language',
+ field=models.CharField(blank=True, default='en', max_length=30),
+ ),
+ ]
diff --git a/mathesar/models/users.py b/mathesar/models/users.py
index 5bcae308bc..025d462b8d 100644
--- a/mathesar/models/users.py
+++ b/mathesar/models/users.py
@@ -15,6 +15,7 @@ class User(AbstractUser):
full_name = models.CharField(max_length=255, blank=True, null=True)
short_name = models.CharField(max_length=255, blank=True, null=True)
password_change_needed = models.BooleanField(default=False)
+ preferred_language = models.CharField(max_length=30, blank=True, default='en')
class Role(models.TextChoices):
diff --git a/mathesar/views.py b/mathesar/views.py
index acf58998d2..b1cd276d76 100644
--- a/mathesar/views.py
+++ b/mathesar/views.py
@@ -111,6 +111,7 @@ def get_common_data(request, database=None, schema=None):
'user': get_user_data(request),
'live_demo_mode': getattr(settings, 'MATHESAR_LIVE_DEMO', False),
'current_release_tag_name': __version__,
+ 'supported_languages': dict(getattr(settings, 'LANGUAGES', [])),
}
From 8e9f5bb821332fe5a89d469f7ce1700e7f3635fc Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 27 Jul 2023 09:44:03 +0000
Subject: [PATCH 003/111] added locale middleware
---
config/settings/common_settings.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/config/settings/common_settings.py b/config/settings/common_settings.py
index 3becf9b3a6..2e52043a01 100644
--- a/config/settings/common_settings.py
+++ b/config/settings/common_settings.py
@@ -15,6 +15,7 @@
from decouple import Csv, config as decouple_config
from dj_database_url import parse as db_url
+from django.utils.translation import gettext_lazy
# We use a 'tuple' with pipes as delimiters as decople naively splits the global
@@ -50,6 +51,7 @@ def pipe_delim(pipe_string):
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
+ "django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
@@ -247,3 +249,10 @@ def pipe_delim(pipe_string):
}
# List of Template names that contains additional script tags to be added to the base template
BASE_TEMPLATE_ADDITIONAL_SCRIPT_TEMPLATES = []
+
+# i18n
+LANGUAGES = [
+ ('en', gettext_lazy('English')),
+ ('ja', gettext_lazy('Japanese')),
+]
+LANGUAGE_COOKIE_NAME = 'user_preferred_language'
From 0917c8c8bc4e32a38c33328eaaa284f51001dfb0 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 27 Jul 2023 15:16:24 +0530
Subject: [PATCH 004/111] preferred lang dropdown in profile page
---
mathesar_ui/src/api/users.ts | 1 +
mathesar_ui/src/stores/users.ts | 4 ++++
.../SelectPreferredLanguage.svelte | 20 +++++++++++++++++
.../UserDetailsForm.svelte | 22 ++++++++++++++++++-
mathesar_ui/src/utils/preloadData.ts | 1 +
5 files changed, 47 insertions(+), 1 deletion(-)
create mode 100644 mathesar_ui/src/systems/users-and-permissions/SelectPreferredLanguage.svelte
diff --git a/mathesar_ui/src/api/users.ts b/mathesar_ui/src/api/users.ts
index f90a168396..50c8ccf9a2 100644
--- a/mathesar_ui/src/api/users.ts
+++ b/mathesar_ui/src/api/users.ts
@@ -12,6 +12,7 @@ export interface UnsavedUser {
email: string | null;
username: string;
password: string;
+ preferred_language: string;
}
export type UserRole = 'viewer' | 'editor' | 'manager';
diff --git a/mathesar_ui/src/stores/users.ts b/mathesar_ui/src/stores/users.ts
index 2ee528618c..aac2107f01 100644
--- a/mathesar_ui/src/stores/users.ts
+++ b/mathesar_ui/src/stores/users.ts
@@ -29,6 +29,8 @@ export class UserModel {
readonly username: User['username'];
+ readonly preferredLanguage: User['preferred_language'];
+
private databaseRoles: Map;
private schemaRoles: Map;
@@ -45,6 +47,7 @@ export class UserModel {
this.fullName = userDetails.full_name;
this.email = userDetails.email;
this.username = userDetails.username;
+ this.preferredLanguage = userDetails.preferred_language;
}
hasPermission(
@@ -119,6 +122,7 @@ export class UserModel {
schema_roles: [...this.schemaRoles.values()],
full_name: this.fullName,
email: this.email,
+ preferred_language: this.preferredLanguage,
};
}
diff --git a/mathesar_ui/src/systems/users-and-permissions/SelectPreferredLanguage.svelte b/mathesar_ui/src/systems/users-and-permissions/SelectPreferredLanguage.svelte
new file mode 100644
index 0000000000..418d3e30dd
--- /dev/null
+++ b/mathesar_ui/src/systems/users-and-permissions/SelectPreferredLanguage.svelte
@@ -0,0 +1,20 @@
+
+
+
diff --git a/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte b/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte
index 252544d5d1..d5cb821e2f 100644
--- a/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte
+++ b/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte
@@ -21,8 +21,12 @@
} from '@mathesar/components/form';
import { iconSave, iconUndo } from '@mathesar/icons';
import { getUserProfileStoreFromContext } from '@mathesar/stores/userProfile';
+ import { locale, setLocale } from '@mathesar/i18n/i18n-svelte';
+ import { loadLocaleAsync } from '@mathesar/i18n/i18n-load';
+ import type { Locales } from '@mathesar/i18n/i18n-types';
import SelectUserType from './SelectUserType.svelte';
import UserFormInput from './UserFormInput.svelte';
+ import SelectPreferredLanguage from './SelectPreferredLanguage.svelte';
const dispatch = createEventDispatcher<{ create: User; update: undefined }>();
const userProfileStore = getUserProfileStoreFromContext();
@@ -41,6 +45,7 @@
),
]);
$: email = optionalField(user?.email ?? '', [isEmail()]);
+ $: preferredLanguage = requiredField(user?.preferred_language ?? '');
$: userType = requiredField<'user' | 'admin' | undefined>(
user?.is_superuser ? 'admin' : 'user',
);
@@ -49,7 +54,7 @@
$: user, password.reset();
$: formFields = (() => {
- const fields = { fullName, username, email, userType };
+ const fields = { fullName, username, email, userType, preferredLanguage };
return isNewUser ? { ...fields, password } : fields;
})();
$: form = makeForm(formFields);
@@ -61,6 +66,7 @@
username: formValues.username,
email: formValues.email,
is_superuser: formValues.userType === 'admin',
+ preferred_language: formValues.preferredLanguage,
};
if (isNewUser && hasProperty(formValues, 'password')) {
@@ -77,6 +83,12 @@
if (isUserUpdatingThemselves && userProfileStore) {
userProfileStore.update((details) => details.with(request));
}
+
+ const updatedLocale = request.preferred_language as Locales;
+ if ($locale !== updatedLocale) {
+ await loadLocaleAsync(updatedLocale);
+ setLocale(updatedLocale);
+ }
dispatch('update');
return;
}
@@ -140,6 +152,14 @@
/>
{/if}
+
+
;
}
function getData(selector: string, retainData = false): T | undefined {
From c9340083329a6a8b756313bef58c37300146f618 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 27 Jul 2023 10:31:21 +0000
Subject: [PATCH 005/111] language switcher for anon users
---
mathesar/templates/mathesar/login_base.html | 20 ++
mathesar/urls.py | 1 +
mathesar_ui/src/i18n/i18n-types.ts | 367 ++++++++++----------
3 files changed, 204 insertions(+), 184 deletions(-)
diff --git a/mathesar/templates/mathesar/login_base.html b/mathesar/templates/mathesar/login_base.html
index 5dcb5ca561..d89ccd1c96 100644
--- a/mathesar/templates/mathesar/login_base.html
+++ b/mathesar/templates/mathesar/login_base.html
@@ -116,6 +116,13 @@
font-size: var(--size-xx-large);
text-align: center;
}
+ .login-card .language-selector {
+ display: block;
+ background-color: transparent;
+ border: 1px solid var(--slate-200);
+ border-radius: 0.285rem;
+ cursor: pointer;
+ }
@media (max-width: 50rem) {
.unsupported-device {
display: block;
@@ -192,5 +199,18 @@
{% block h1 %} {% endblock %}
{% block box_content %} {% endblock %}
+
{% endblock %}
diff --git a/mathesar/urls.py b/mathesar/urls.py
index 931556ab67..0bafa8e3a2 100644
--- a/mathesar/urls.py
+++ b/mathesar/urls.py
@@ -48,6 +48,7 @@
path('administration/update/', views.admin_home, name='admin_update'),
path('db/', views.home, name='db_home'),
path('db//', views.schemas, name='schemas'),
+ path('i18n/', include('django.conf.urls.i18n')),
re_path(
r'^db/(?P\w+)/(?P\w+)/',
views.schema_home,
diff --git a/mathesar_ui/src/i18n/i18n-types.ts b/mathesar_ui/src/i18n/i18n-types.ts
index 9b8ff873e2..27f341c5f9 100644
--- a/mathesar_ui/src/i18n/i18n-types.ts
+++ b/mathesar_ui/src/i18n/i18n-types.ts
@@ -3,196 +3,195 @@
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint eslint-comments/disable-enable-pair: [error, {allowWholeFile: true}] */
/* eslint-disable */
-import type {
- BaseTranslation as BaseTranslationType,
- LocalizedString,
-} from 'typesafe-i18n';
+import type { BaseTranslation as BaseTranslationType, LocalizedString } from 'typesafe-i18n'
-export type BaseTranslation = BaseTranslationType;
-export type BaseLocale = 'en';
+export type BaseTranslation = BaseTranslationType
+export type BaseLocale = 'en'
-export type Locales = 'en' | 'ja';
+export type Locales =
+ | 'en'
+ | 'ja'
-export type Translation = RootTranslation;
+export type Translation = RootTranslation
-export type Translations = RootTranslation;
+export type Translations = RootTranslation
type RootTranslation = {
- general: {
- /**
- * Import
- */
- import: string;
- /**
- * One to Many
- */
- oneToMany: string;
- /**
- * Many to One
- */
- manyToOne: string;
- /**
- * Many to Many
- */
- manyToMany: string;
- /**
- * Linking Table
- */
- linkingTable: string;
- };
- importUploadPage: {
- /**
- * Upload a file
- */
- uploadAFile: string;
- /**
- * Provide a URL to the file
- */
- provideUrlToFile: string;
- /**
- * Copy and Paste Text
- */
- copyAndPasteText: string;
- /**
- * Unable to create a table from the uploaded data
- */
- unableToCreateTableFromUpload: string;
- /**
- * Create a table by importing your data
- */
- createATableByImporting: string;
- /**
- * Uploading Data
- */
- uploadingData: string;
- /**
- * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
- */
- largeDataTakesTimeWarning: string;
- /**
- * How would you like to import your data?
- */
- howWouldYouLikeToImport: string;
- /**
- * Upload failed
- */
- uploadFailed: string;
- /**
- * Preparing Preview
- */
- preparingPreview: string;
- /**
- * Failed to import data
- */
- failedToImport: string;
- };
- linkTypeOptions: {
- /**
- * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
- */
- oneToManyDescription: string;
- /**
- * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
- */
- manyToOneDescription: string;
- /**
- * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
- */
- manyToManyDescription: string;
- /**
- * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
- */
- manyToManySelfReferential: string;
- };
-};
+ general: {
+ /**
+ * Import
+ */
+ 'import': string
+ /**
+ * One to Many
+ */
+ oneToMany: string
+ /**
+ * Many to One
+ */
+ manyToOne: string
+ /**
+ * Many to Many
+ */
+ manyToMany: string
+ /**
+ * Linking Table
+ */
+ linkingTable: string
+ }
+ importUploadPage: {
+ /**
+ * Upload a file
+ */
+ uploadAFile: string
+ /**
+ * Provide a URL to the file
+ */
+ provideUrlToFile: string
+ /**
+ * Copy and Paste Text
+ */
+ copyAndPasteText: string
+ /**
+ * Unable to create a table from the uploaded data
+ */
+ unableToCreateTableFromUpload: string
+ /**
+ * Create a table by importing your data
+ */
+ createATableByImporting: string
+ /**
+ * Uploading Data
+ */
+ uploadingData: string
+ /**
+ * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
+ */
+ largeDataTakesTimeWarning: string
+ /**
+ * How would you like to import your data?
+ */
+ howWouldYouLikeToImport: string
+ /**
+ * Upload failed
+ */
+ uploadFailed: string
+ /**
+ * Preparing Preview
+ */
+ preparingPreview: string
+ /**
+ * Failed to import data
+ */
+ failedToImport: string
+ }
+ linkTypeOptions: {
+ /**
+ * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
+ */
+ oneToManyDescription: string
+ /**
+ * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
+ */
+ manyToOneDescription: string
+ /**
+ * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
+ */
+ manyToManyDescription: string
+ /**
+ * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
+ */
+ manyToManySelfReferential: string
+ }
+}
export type TranslationFunctions = {
- general: {
- /**
- * Import
- */
- import: () => LocalizedString;
- /**
- * One to Many
- */
- oneToMany: () => LocalizedString;
- /**
- * Many to One
- */
- manyToOne: () => LocalizedString;
- /**
- * Many to Many
- */
- manyToMany: () => LocalizedString;
- /**
- * Linking Table
- */
- linkingTable: () => LocalizedString;
- };
- importUploadPage: {
- /**
- * Upload a file
- */
- uploadAFile: () => LocalizedString;
- /**
- * Provide a URL to the file
- */
- provideUrlToFile: () => LocalizedString;
- /**
- * Copy and Paste Text
- */
- copyAndPasteText: () => LocalizedString;
- /**
- * Unable to create a table from the uploaded data
- */
- unableToCreateTableFromUpload: () => LocalizedString;
- /**
- * Create a table by importing your data
- */
- createATableByImporting: () => LocalizedString;
- /**
- * Uploading Data
- */
- uploadingData: () => LocalizedString;
- /**
- * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
- */
- largeDataTakesTimeWarning: () => LocalizedString;
- /**
- * How would you like to import your data?
- */
- howWouldYouLikeToImport: () => LocalizedString;
- /**
- * Upload failed
- */
- uploadFailed: () => LocalizedString;
- /**
- * Preparing Preview
- */
- preparingPreview: () => LocalizedString;
- /**
- * Failed to import data
- */
- failedToImport: () => LocalizedString;
- };
- linkTypeOptions: {
- /**
- * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
- */
- oneToManyDescription: () => LocalizedString;
- /**
- * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
- */
- manyToOneDescription: () => LocalizedString;
- /**
- * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
- */
- manyToManyDescription: () => LocalizedString;
- /**
- * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
- */
- manyToManySelfReferential: () => LocalizedString;
- };
-};
+ general: {
+ /**
+ * Import
+ */
+ 'import': () => LocalizedString
+ /**
+ * One to Many
+ */
+ oneToMany: () => LocalizedString
+ /**
+ * Many to One
+ */
+ manyToOne: () => LocalizedString
+ /**
+ * Many to Many
+ */
+ manyToMany: () => LocalizedString
+ /**
+ * Linking Table
+ */
+ linkingTable: () => LocalizedString
+ }
+ importUploadPage: {
+ /**
+ * Upload a file
+ */
+ uploadAFile: () => LocalizedString
+ /**
+ * Provide a URL to the file
+ */
+ provideUrlToFile: () => LocalizedString
+ /**
+ * Copy and Paste Text
+ */
+ copyAndPasteText: () => LocalizedString
+ /**
+ * Unable to create a table from the uploaded data
+ */
+ unableToCreateTableFromUpload: () => LocalizedString
+ /**
+ * Create a table by importing your data
+ */
+ createATableByImporting: () => LocalizedString
+ /**
+ * Uploading Data
+ */
+ uploadingData: () => LocalizedString
+ /**
+ * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
+ */
+ largeDataTakesTimeWarning: () => LocalizedString
+ /**
+ * How would you like to import your data?
+ */
+ howWouldYouLikeToImport: () => LocalizedString
+ /**
+ * Upload failed
+ */
+ uploadFailed: () => LocalizedString
+ /**
+ * Preparing Preview
+ */
+ preparingPreview: () => LocalizedString
+ /**
+ * Failed to import data
+ */
+ failedToImport: () => LocalizedString
+ }
+ linkTypeOptions: {
+ /**
+ * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
+ */
+ oneToManyDescription: () => LocalizedString
+ /**
+ * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
+ */
+ manyToOneDescription: () => LocalizedString
+ /**
+ * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
+ */
+ manyToManyDescription: () => LocalizedString
+ /**
+ * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
+ */
+ manyToManySelfReferential: () => LocalizedString
+ }
+}
-export type Formatters = {};
+export type Formatters = {}
From 1e418f1e8943024e969a7a1ce925ada1e13bfb5e Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 27 Jul 2023 16:12:54 +0530
Subject: [PATCH 006/111] lint fixes
---
mathesar_ui/src/i18n/i18n-types.ts | 367 +++++++++++++++--------------
1 file changed, 184 insertions(+), 183 deletions(-)
diff --git a/mathesar_ui/src/i18n/i18n-types.ts b/mathesar_ui/src/i18n/i18n-types.ts
index 27f341c5f9..9b8ff873e2 100644
--- a/mathesar_ui/src/i18n/i18n-types.ts
+++ b/mathesar_ui/src/i18n/i18n-types.ts
@@ -3,195 +3,196 @@
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint eslint-comments/disable-enable-pair: [error, {allowWholeFile: true}] */
/* eslint-disable */
-import type { BaseTranslation as BaseTranslationType, LocalizedString } from 'typesafe-i18n'
+import type {
+ BaseTranslation as BaseTranslationType,
+ LocalizedString,
+} from 'typesafe-i18n';
-export type BaseTranslation = BaseTranslationType
-export type BaseLocale = 'en'
+export type BaseTranslation = BaseTranslationType;
+export type BaseLocale = 'en';
-export type Locales =
- | 'en'
- | 'ja'
+export type Locales = 'en' | 'ja';
-export type Translation = RootTranslation
+export type Translation = RootTranslation;
-export type Translations = RootTranslation
+export type Translations = RootTranslation;
type RootTranslation = {
- general: {
- /**
- * Import
- */
- 'import': string
- /**
- * One to Many
- */
- oneToMany: string
- /**
- * Many to One
- */
- manyToOne: string
- /**
- * Many to Many
- */
- manyToMany: string
- /**
- * Linking Table
- */
- linkingTable: string
- }
- importUploadPage: {
- /**
- * Upload a file
- */
- uploadAFile: string
- /**
- * Provide a URL to the file
- */
- provideUrlToFile: string
- /**
- * Copy and Paste Text
- */
- copyAndPasteText: string
- /**
- * Unable to create a table from the uploaded data
- */
- unableToCreateTableFromUpload: string
- /**
- * Create a table by importing your data
- */
- createATableByImporting: string
- /**
- * Uploading Data
- */
- uploadingData: string
- /**
- * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
- */
- largeDataTakesTimeWarning: string
- /**
- * How would you like to import your data?
- */
- howWouldYouLikeToImport: string
- /**
- * Upload failed
- */
- uploadFailed: string
- /**
- * Preparing Preview
- */
- preparingPreview: string
- /**
- * Failed to import data
- */
- failedToImport: string
- }
- linkTypeOptions: {
- /**
- * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
- */
- oneToManyDescription: string
- /**
- * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
- */
- manyToOneDescription: string
- /**
- * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
- */
- manyToManyDescription: string
- /**
- * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
- */
- manyToManySelfReferential: string
- }
-}
+ general: {
+ /**
+ * Import
+ */
+ import: string;
+ /**
+ * One to Many
+ */
+ oneToMany: string;
+ /**
+ * Many to One
+ */
+ manyToOne: string;
+ /**
+ * Many to Many
+ */
+ manyToMany: string;
+ /**
+ * Linking Table
+ */
+ linkingTable: string;
+ };
+ importUploadPage: {
+ /**
+ * Upload a file
+ */
+ uploadAFile: string;
+ /**
+ * Provide a URL to the file
+ */
+ provideUrlToFile: string;
+ /**
+ * Copy and Paste Text
+ */
+ copyAndPasteText: string;
+ /**
+ * Unable to create a table from the uploaded data
+ */
+ unableToCreateTableFromUpload: string;
+ /**
+ * Create a table by importing your data
+ */
+ createATableByImporting: string;
+ /**
+ * Uploading Data
+ */
+ uploadingData: string;
+ /**
+ * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
+ */
+ largeDataTakesTimeWarning: string;
+ /**
+ * How would you like to import your data?
+ */
+ howWouldYouLikeToImport: string;
+ /**
+ * Upload failed
+ */
+ uploadFailed: string;
+ /**
+ * Preparing Preview
+ */
+ preparingPreview: string;
+ /**
+ * Failed to import data
+ */
+ failedToImport: string;
+ };
+ linkTypeOptions: {
+ /**
+ * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
+ */
+ oneToManyDescription: string;
+ /**
+ * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
+ */
+ manyToOneDescription: string;
+ /**
+ * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
+ */
+ manyToManyDescription: string;
+ /**
+ * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
+ */
+ manyToManySelfReferential: string;
+ };
+};
export type TranslationFunctions = {
- general: {
- /**
- * Import
- */
- 'import': () => LocalizedString
- /**
- * One to Many
- */
- oneToMany: () => LocalizedString
- /**
- * Many to One
- */
- manyToOne: () => LocalizedString
- /**
- * Many to Many
- */
- manyToMany: () => LocalizedString
- /**
- * Linking Table
- */
- linkingTable: () => LocalizedString
- }
- importUploadPage: {
- /**
- * Upload a file
- */
- uploadAFile: () => LocalizedString
- /**
- * Provide a URL to the file
- */
- provideUrlToFile: () => LocalizedString
- /**
- * Copy and Paste Text
- */
- copyAndPasteText: () => LocalizedString
- /**
- * Unable to create a table from the uploaded data
- */
- unableToCreateTableFromUpload: () => LocalizedString
- /**
- * Create a table by importing your data
- */
- createATableByImporting: () => LocalizedString
- /**
- * Uploading Data
- */
- uploadingData: () => LocalizedString
- /**
- * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
- */
- largeDataTakesTimeWarning: () => LocalizedString
- /**
- * How would you like to import your data?
- */
- howWouldYouLikeToImport: () => LocalizedString
- /**
- * Upload failed
- */
- uploadFailed: () => LocalizedString
- /**
- * Preparing Preview
- */
- preparingPreview: () => LocalizedString
- /**
- * Failed to import data
- */
- failedToImport: () => LocalizedString
- }
- linkTypeOptions: {
- /**
- * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
- */
- oneToManyDescription: () => LocalizedString
- /**
- * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
- */
- manyToOneDescription: () => LocalizedString
- /**
- * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
- */
- manyToManyDescription: () => LocalizedString
- /**
- * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
- */
- manyToManySelfReferential: () => LocalizedString
- }
-}
+ general: {
+ /**
+ * Import
+ */
+ import: () => LocalizedString;
+ /**
+ * One to Many
+ */
+ oneToMany: () => LocalizedString;
+ /**
+ * Many to One
+ */
+ manyToOne: () => LocalizedString;
+ /**
+ * Many to Many
+ */
+ manyToMany: () => LocalizedString;
+ /**
+ * Linking Table
+ */
+ linkingTable: () => LocalizedString;
+ };
+ importUploadPage: {
+ /**
+ * Upload a file
+ */
+ uploadAFile: () => LocalizedString;
+ /**
+ * Provide a URL to the file
+ */
+ provideUrlToFile: () => LocalizedString;
+ /**
+ * Copy and Paste Text
+ */
+ copyAndPasteText: () => LocalizedString;
+ /**
+ * Unable to create a table from the uploaded data
+ */
+ unableToCreateTableFromUpload: () => LocalizedString;
+ /**
+ * Create a table by importing your data
+ */
+ createATableByImporting: () => LocalizedString;
+ /**
+ * Uploading Data
+ */
+ uploadingData: () => LocalizedString;
+ /**
+ * Large data sets can sometimes take several minutes to process. Please do not leave this page or close the browser tab while import is in progress.
+ */
+ largeDataTakesTimeWarning: () => LocalizedString;
+ /**
+ * How would you like to import your data?
+ */
+ howWouldYouLikeToImport: () => LocalizedString;
+ /**
+ * Upload failed
+ */
+ uploadFailed: () => LocalizedString;
+ /**
+ * Preparing Preview
+ */
+ preparingPreview: () => LocalizedString;
+ /**
+ * Failed to import data
+ */
+ failedToImport: () => LocalizedString;
+ };
+ linkTypeOptions: {
+ /**
+ * One <>baseTable<> record can be linked from multiple <>targetTable<> records.
+ */
+ oneToManyDescription: () => LocalizedString;
+ /**
+ * Multiple <>baseTable<> records can link to the same <>targetTable<> record.
+ */
+ manyToOneDescription: () => LocalizedString;
+ /**
+ * Multiple <>baseTable<> and <>targetTable<> records can link to each other through a new <>mappingTable<>
+ */
+ manyToManyDescription: () => LocalizedString;
+ /**
+ * Multiple <>baseTable<> records can link to each other through a new <>mapping<>
+ */
+ manyToManySelfReferential: () => LocalizedString;
+ };
+};
-export type Formatters = {}
+export type Formatters = {};
From 1738aca591db359496eca1185bffb369b08cb7e4 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Wed, 6 Sep 2023 15:16:17 +0530
Subject: [PATCH 007/111] renamed loadTranslationsIntoMemory to
loadTranslations
---
mathesar_ui/src/App.svelte | 4 ++--
mathesar_ui/src/i18n/i18n-load.ts | 5 +----
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/mathesar_ui/src/App.svelte b/mathesar_ui/src/App.svelte
index 391414ef5b..ed1e4d2517 100644
--- a/mathesar_ui/src/App.svelte
+++ b/mathesar_ui/src/App.svelte
@@ -5,13 +5,13 @@
import RootRoute from './routes/RootRoute.svelte';
import { setLocale } from './i18n/i18n-svelte';
import ErrorBox from './components/message-boxes/ErrorBox.svelte';
- import { loadTranslationsIntoMemory } from './i18n/i18n-load';
+ import { loadTranslations } from './i18n/i18n-load';
let isTranslationsLoaded = false;
const checkTranslationsAvailableInterval = setInterval(() => {
const { translations } = window;
if (translations) {
- loadTranslationsIntoMemory(
+ loadTranslations(
translations.lang,
JSON.parse(translations.translationStrings),
);
diff --git a/mathesar_ui/src/i18n/i18n-load.ts b/mathesar_ui/src/i18n/i18n-load.ts
index 6e0aabee3b..975abf24f7 100644
--- a/mathesar_ui/src/i18n/i18n-load.ts
+++ b/mathesar_ui/src/i18n/i18n-load.ts
@@ -31,10 +31,7 @@ export async function loadLocaleAsync(locale: Locales): Promise {
loadFormatters(locale);
}
-export function loadTranslationsIntoMemory(
- locale: Locales,
- translations: Translations,
-) {
+export function loadTranslations(locale: Locales, translations: Translations) {
updateTranslationsDictionary(locale, translations);
loadFormatters(locale);
}
From b5c5bde9ab57d42a5b0f1ec9be271558013d5477 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Wed, 6 Sep 2023 16:13:47 +0530
Subject: [PATCH 008/111] made translations script async
---
mathesar/templates/mathesar/index.html | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/mathesar/templates/mathesar/index.html b/mathesar/templates/mathesar/index.html
index 2d4e616ef6..fd95be1b96 100644
--- a/mathesar/templates/mathesar/index.html
+++ b/mathesar/templates/mathesar/index.html
@@ -19,8 +19,9 @@
{% endfor %}
{% endif %}
-
+
{% endif %}
{% endblock %}
From 0e8e6748b874d2aaf75079832d3d4b2a673617e8 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Wed, 6 Sep 2023 17:06:42 +0530
Subject: [PATCH 009/111] renamed preferred_language to display_language
---
config/context_processors.py | 10 +++++-----
config/settings/common_settings.py | 2 +-
mathesar/api/ui/serializers/users.py | 2 +-
...language.py => 0005_user_display_language.py} | 6 +++---
mathesar/models/users.py | 2 +-
mathesar/templates/mathesar/index.html | 4 ++--
mathesar/utils/frontend.py | 10 +++++-----
mathesar_ui/src/api/users.ts | 2 +-
mathesar_ui/src/stores/users.ts | 7 ++++---
...guage.svelte => SelectDisplayLanguage.svelte} | 0
.../users-and-permissions/UserDetailsForm.svelte | 16 ++++++++--------
11 files changed, 31 insertions(+), 30 deletions(-)
rename mathesar/migrations/{0004_user_preferred_language.py => 0005_user_display_language.py} (67%)
rename mathesar_ui/src/systems/users-and-permissions/{SelectPreferredLanguage.svelte => SelectDisplayLanguage.svelte} (100%)
diff --git a/config/context_processors.py b/config/context_processors.py
index 1828e543bb..902505045d 100644
--- a/config/context_processors.py
+++ b/config/context_processors.py
@@ -4,11 +4,11 @@
def frontend_settings(request):
- preferred_language = get_user_preferred_language_from_request(request)
+ display_language = get_display_language_from_request(request)
frontend_settings = {
'development_mode': settings.MATHESAR_MODE == 'DEVELOPMENT',
- 'manifest_data': get_manifest_data(preferred_language),
- 'preferred_language': preferred_language,
+ 'manifest_data': get_manifest_data(display_language),
+ 'display_language': display_language,
'live_demo_mode': getattr(settings, 'MATHESAR_LIVE_DEMO', False),
'live_demo_username': getattr(settings, 'MATHESAR_LIVE_DEMO_USERNAME', None),
'live_demo_password': getattr(settings, 'MATHESAR_LIVE_DEMO_PASSWORD', None),
@@ -19,12 +19,12 @@ def frontend_settings(request):
return frontend_settings
-def get_user_preferred_language_from_request(request):
+def get_display_language_from_request(request):
# https://docs.djangoproject.com/en/4.2/topics/i18n/translation/#how-django-discovers-language-preference
# This automatically fallbacks to en because of https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-LANGUAGE_CODE
lang_from_locale_middleware = request.LANGUAGE_CODE
if request.user.is_authenticated:
- return request.user.preferred_language or lang_from_locale_middleware
+ return request.user.display_language or lang_from_locale_middleware
else:
return lang_from_locale_middleware
diff --git a/config/settings/common_settings.py b/config/settings/common_settings.py
index 8659cf3b9f..a2dc749b57 100644
--- a/config/settings/common_settings.py
+++ b/config/settings/common_settings.py
@@ -256,4 +256,4 @@ def pipe_delim(pipe_string):
('en', gettext_lazy('English')),
('ja', gettext_lazy('Japanese')),
]
-LANGUAGE_COOKIE_NAME = 'user_preferred_language'
+LANGUAGE_COOKIE_NAME = 'display_language'
diff --git a/mathesar/api/ui/serializers/users.py b/mathesar/api/ui/serializers/users.py
index 78b657cb97..199c439ac4 100644
--- a/mathesar/api/ui/serializers/users.py
+++ b/mathesar/api/ui/serializers/users.py
@@ -40,7 +40,7 @@ class Meta:
'is_superuser',
'database_roles',
'schema_roles',
- 'preferred_language'
+ 'display_language'
]
extra_kwargs = {
'password': {'write_only': True},
diff --git a/mathesar/migrations/0004_user_preferred_language.py b/mathesar/migrations/0005_user_display_language.py
similarity index 67%
rename from mathesar/migrations/0004_user_preferred_language.py
rename to mathesar/migrations/0005_user_display_language.py
index be05706c91..c2eb798493 100644
--- a/mathesar/migrations/0004_user_preferred_language.py
+++ b/mathesar/migrations/0005_user_display_language.py
@@ -1,4 +1,4 @@
-# Generated by Django 3.1.14 on 2023-07-27 09:15
+# Generated by Django 3.1.14 on 2023-09-06 11:25
from django.db import migrations, models
@@ -6,13 +6,13 @@
class Migration(migrations.Migration):
dependencies = [
- ('mathesar', '0003_datafile_max_level'),
+ ('mathesar', '0004_shares'),
]
operations = [
migrations.AddField(
model_name='user',
- name='preferred_language',
+ name='display_language',
field=models.CharField(blank=True, default='en', max_length=30),
),
]
diff --git a/mathesar/models/users.py b/mathesar/models/users.py
index 025d462b8d..9e3fcbe86a 100644
--- a/mathesar/models/users.py
+++ b/mathesar/models/users.py
@@ -15,7 +15,7 @@ class User(AbstractUser):
full_name = models.CharField(max_length=255, blank=True, null=True)
short_name = models.CharField(max_length=255, blank=True, null=True)
password_change_needed = models.BooleanField(default=False)
- preferred_language = models.CharField(max_length=30, blank=True, default='en')
+ display_language = models.CharField(max_length=30, blank=True, default='en')
class Role(models.TextChoices):
diff --git a/mathesar/templates/mathesar/index.html b/mathesar/templates/mathesar/index.html
index fd95be1b96..cc6cea11aa 100644
--- a/mathesar/templates/mathesar/index.html
+++ b/mathesar/templates/mathesar/index.html
@@ -22,10 +22,10 @@
{% comment %} Making it async to start the execution as soon as its downloaded without making it wait for the HTML to be parsed {% endcomment %}
@@ -62,16 +62,6 @@
nomodule
src="{% static manifest_data.legacy_polyfill_js %}"
>
-
diff --git a/mathesar_ui/src/global.d.ts b/mathesar_ui/src/global.d.ts
index 41aa976973..dfbdbd61e5 100644
--- a/mathesar_ui/src/global.d.ts
+++ b/mathesar_ui/src/global.d.ts
@@ -7,5 +7,9 @@ declare module '*.mdx' {
}
interface Window {
- translations: { lang: Locales; translationStrings: string } | undefined;
+ mathesar:
+ | {
+ translations: { lang: Locales; translationStrings: string } | undefined;
+ }
+ | undefined;
}
From c5ed4bcd87dca4c1efe9b235923c933a3884da4f Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Tue, 19 Sep 2023 15:48:39 +0530
Subject: [PATCH 016/111] lint fixes
---
mathesar_ui/src/App.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mathesar_ui/src/App.svelte b/mathesar_ui/src/App.svelte
index 5eac49922f..42108129c6 100644
--- a/mathesar_ui/src/App.svelte
+++ b/mathesar_ui/src/App.svelte
@@ -36,7 +36,7 @@
* it as a default exported module. Otherwise vite converts the
* default export to named exports internally for the sake of optimization.
*/
- loadLocaleAsync('en');
+ void loadLocaleAsync('en');
}
const commonData = preloadCommonData();
From 25c89ce4a16ea2af74322def5f540ca8e8325cd1 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Tue, 19 Sep 2023 15:50:02 +0530
Subject: [PATCH 017/111] do not read legacy builds for translations files
---
mathesar/utils/frontend.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/mathesar/utils/frontend.py b/mathesar/utils/frontend.py
index 8c0ad8fff4..ca4f3e084d 100644
--- a/mathesar/utils/frontend.py
+++ b/mathesar/utils/frontend.py
@@ -27,7 +27,6 @@ def get_manifest_data():
for locale, _ in settings.LANGUAGES or []:
manifest_data[locale] = raw_data[f'src/i18n/{locale}/index.ts']
- manifest_data[f"{locale}-legacy"] = raw_data[f'src/i18n/{locale}/index-legacy.ts']
# Cache data for 1 hour
cache.set('manifest_data', manifest_data, 60 * 60)
From 737effa9e60660e58e39c28b60c1bcdbe94de56e Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Tue, 19 Sep 2023 16:34:35 +0530
Subject: [PATCH 018/111] render page when loading default lang translations
---
mathesar_ui/src/App.svelte | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/mathesar_ui/src/App.svelte b/mathesar_ui/src/App.svelte
index 42108129c6..d0e4ceb352 100644
--- a/mathesar_ui/src/App.svelte
+++ b/mathesar_ui/src/App.svelte
@@ -15,9 +15,9 @@
* 2. And then make it available for the entry(App.svelte)
* file to load them into memory.
* the index.html loads it as using a script tag and attach it
- * to the window's global object which is being read here
+ * to the window object which is being read here
*/
- try {
+ void (async () => {
const { translations } = window.mathesar || {};
if (translations) {
loadTranslations(
@@ -26,18 +26,19 @@
);
setLocale(translations.lang);
isTranslationsLoaded = true;
+ } else {
+ /**
+ * !!! CAUTION: DO NOT REMOVE THIS !!!
+ * Reason: Apart from loading the `en` translations as default
+ * when there are translations on the window object,
+ * this also tells the vite bundler to bundle
+ * it as a default exported module. Otherwise vite converts the
+ * default export to named exports internally for the sake of optimization.
+ */
+ await loadLocaleAsync('en');
+ isTranslationsLoaded = true;
}
- } catch {
- /**
- * !!! CAUTION: DO NOT REMOVE THIS !!!
- * Reason: Apart from loading the `en` translations as default
- * when something fails while reading the window's global
- * object, this also tells the vite bundler to bundle
- * it as a default exported module. Otherwise vite converts the
- * default export to named exports internally for the sake of optimization.
- */
- void loadLocaleAsync('en');
- }
+ })();
const commonData = preloadCommonData();
From 0bb7d3888e9eeb35378eaa7799d97366dca41b7c Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Fri, 22 Sep 2023 12:42:31 +0530
Subject: [PATCH 019/111] add database connection page
---
mathesar/urls.py | 2 +
mathesar/views.py | 15 ++
mathesar_ui/src/AppTypes.ts | 5 +
mathesar_ui/src/api/databaseConnection.ts | 19 ++
.../pages/admin-users/AdminNavigation.svelte | 17 +-
.../AddDatabaseConnection.svelte | 35 ++++
.../DatabaseConnectionForm.svelte | 178 ++++++++++++++++++
.../EditDatabaseConnection.svelte | 15 ++
mathesar_ui/src/routes/AdminRoute.svelte | 11 +-
.../src/routes/AuthenticatedRoutes.svelte | 2 +-
.../src/routes/DatabaseConnectionRoute.svelte | 13 ++
mathesar_ui/src/routes/urls.ts | 7 +
.../UserFormInput.svelte | 7 +
13 files changed, 323 insertions(+), 3 deletions(-)
create mode 100644 mathesar_ui/src/api/databaseConnection.ts
create mode 100644 mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
create mode 100644 mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
create mode 100644 mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
create mode 100644 mathesar_ui/src/routes/DatabaseConnectionRoute.svelte
diff --git a/mathesar/urls.py b/mathesar/urls.py
index 62a91e0fe2..60ea9234ec 100644
--- a/mathesar/urls.py
+++ b/mathesar/urls.py
@@ -53,6 +53,8 @@
path('administration/users/', views.admin_home, name='admin_users_home'),
path('administration/users//', views.admin_home, name='admin_users_edit'),
path('administration/update/', views.admin_home, name='admin_update'),
+ path('administration/db-connection/add/', views.add_database_connection, name='add_database_connection'),
+ path('administration/db-connection/edit/', views.edit_database_connection, name='edit_database_connection'),
path('shares/tables//', views.shared_table, name='shared_table'),
path('shares/explorations//', views.shared_query, name='shared_query'),
path('db/', views.home, name='db_home'),
diff --git a/mathesar/views.py b/mathesar/views.py
index c015fda19b..aaa4689e21 100644
--- a/mathesar/views.py
+++ b/mathesar/views.py
@@ -288,6 +288,21 @@ def schemas(request, db_name):
})
+@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
diff --git a/mathesar_ui/src/AppTypes.ts b/mathesar_ui/src/AppTypes.ts
index d6d46b1fe3..c244eb9d0d 100644
--- a/mathesar_ui/src/AppTypes.ts
+++ b/mathesar_ui/src/AppTypes.ts
@@ -5,6 +5,11 @@ export interface Database {
name: string;
deleted: boolean;
supported_types: string[];
+ db_name: string;
+ editable: boolean;
+ username: string;
+ host: string;
+ port: string;
}
export interface DBObjectEntry {
diff --git a/mathesar_ui/src/api/databaseConnection.ts b/mathesar_ui/src/api/databaseConnection.ts
new file mode 100644
index 0000000000..cdf65d7461
--- /dev/null
+++ b/mathesar_ui/src/api/databaseConnection.ts
@@ -0,0 +1,19 @@
+import type { Database } from '@mathesar/AppTypes';
+import { getAPI, patchAPI, postAPI } from './utils/requestUtils';
+
+export interface NewDatabaseConnection {
+ name: string;
+ db_name: string;
+ username: string;
+ host: string;
+ port: string;
+ password: string;
+}
+
+function add(connectionDetails: NewDatabaseConnection) {
+ return postAPI('/api/db/v0/databases/', connectionDetails);
+}
+
+export default {
+ add,
+};
diff --git a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
index 1b419287e7..af9ae8f165 100644
--- a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
+++ b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
@@ -1,8 +1,13 @@
+
+
+
+ Add Database Connection
+
+
+
+
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
new file mode 100644
index 0000000000..b378802cf2
--- /dev/null
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
new file mode 100644
index 0000000000..447c1cf6a6
--- /dev/null
+++ b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
@@ -0,0 +1,15 @@
+
+
+
+Edit DB Connection for {databaseName}
diff --git a/mathesar_ui/src/routes/AdminRoute.svelte b/mathesar_ui/src/routes/AdminRoute.svelte
index 39fe9713fd..d6603458b3 100644
--- a/mathesar_ui/src/routes/AdminRoute.svelte
+++ b/mathesar_ui/src/routes/AdminRoute.svelte
@@ -8,8 +8,13 @@
import SoftwareUpdate from '@mathesar/pages/admin-update/SoftwareUpdatePage.svelte';
import AdminNavigation from '@mathesar/pages/admin-users/AdminNavigation.svelte';
import PageLayoutWithSidebar from '@mathesar/layouts/PageLayoutWithSidebar.svelte';
- import { ADMIN_UPDATE_PAGE_URL, ADMIN_URL } from './urls';
+ import {
+ ADMIN_UPDATE_PAGE_URL,
+ ADMIN_URL,
+ DATABASE_CONNECTION_SLUG,
+ } from './urls';
import UsersRoute from './UsersRoute.svelte';
+ import DatabaseConnectionRoute from './DatabaseConnectionRoute.svelte';
+
+
+
+
diff --git a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
index a792229898..2cda4b8970 100644
--- a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
+++ b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
@@ -33,5 +33,5 @@
{/if}
-
+
diff --git a/mathesar_ui/src/routes/DatabaseConnectionRoute.svelte b/mathesar_ui/src/routes/DatabaseConnectionRoute.svelte
new file mode 100644
index 0000000000..aea981c2e2
--- /dev/null
+++ b/mathesar_ui/src/routes/DatabaseConnectionRoute.svelte
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/mathesar_ui/src/routes/urls.ts b/mathesar_ui/src/routes/urls.ts
index 2cd56707eb..b3f8999260 100644
--- a/mathesar_ui/src/routes/urls.ts
+++ b/mathesar_ui/src/routes/urls.ts
@@ -115,6 +115,13 @@ export const ADMIN_USERS_PAGE_URL = `${ADMIN_URL}users/`;
export const ADMIN_USERS_PAGE_ADD_NEW_URL = `${ADMIN_URL}users/new/`;
export const LOGOUT_URL = '/auth/logout/';
+export const DATABASE_CONNECTION_SLUG = 'db-connection';
+export const ADD_DATABASE_CONNECTION_URL = `${ADMIN_URL}${DATABASE_CONNECTION_SLUG}/add/`;
+
+export function getDatabaseConnectionEditUrl(databaseName: string) {
+ return `${ADMIN_URL}${DATABASE_CONNECTION_SLUG}/edit/${databaseName}/`;
+}
+
export function getEditUsersPageUrl(userId: number) {
return `${ADMIN_USERS_PAGE_URL}${userId}/`;
}
diff --git a/mathesar_ui/src/systems/users-and-permissions/UserFormInput.svelte b/mathesar_ui/src/systems/users-and-permissions/UserFormInput.svelte
index 19154ed14e..8e81a7eec3 100644
--- a/mathesar_ui/src/systems/users-and-permissions/UserFormInput.svelte
+++ b/mathesar_ui/src/systems/users-and-permissions/UserFormInput.svelte
@@ -48,5 +48,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);
}
From e401e9f49ef26df0b9a1f7de38ccb766f2e85788 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Sat, 23 Sep 2023 01:18:52 +0530
Subject: [PATCH 020/111] edit database connection
---
mathesar/urls.py | 2 +-
mathesar_ui/src/api/databaseConnection.ts | 13 ++-
.../pages/admin-users/AdminNavigation.svelte | 2 +-
.../AddDatabaseConnection.svelte | 6 +-
.../DatabaseConnectionForm.svelte | 41 +++++++--
.../EditDatabaseConnection.svelte | 23 ++++-
.../src/pages/database/ConnectionError.svelte | 38 +++++++++
.../src/pages/database/DatabaseDetails.svelte | 85 +++++++++++--------
.../src/routes/DatabaseConnectionRoute.svelte | 9 +-
9 files changed, 167 insertions(+), 52 deletions(-)
create mode 100644 mathesar_ui/src/pages/database/ConnectionError.svelte
diff --git a/mathesar/urls.py b/mathesar/urls.py
index 60ea9234ec..734d097b7b 100644
--- a/mathesar/urls.py
+++ b/mathesar/urls.py
@@ -54,7 +54,7 @@
path('administration/users//', views.admin_home, name='admin_users_edit'),
path('administration/update/', views.admin_home, name='admin_update'),
path('administration/db-connection/add/', views.add_database_connection, name='add_database_connection'),
- path('administration/db-connection/edit/', views.edit_database_connection, name='edit_database_connection'),
+ path('administration/db-connection/edit//', views.edit_database_connection, name='edit_database_connection'),
path('shares/tables//', views.shared_table, name='shared_table'),
path('shares/explorations//', views.shared_query, name='shared_query'),
path('db/', views.home, name='db_home'),
diff --git a/mathesar_ui/src/api/databaseConnection.ts b/mathesar_ui/src/api/databaseConnection.ts
index cdf65d7461..b36e2f61cf 100644
--- a/mathesar_ui/src/api/databaseConnection.ts
+++ b/mathesar_ui/src/api/databaseConnection.ts
@@ -1,7 +1,7 @@
import type { Database } from '@mathesar/AppTypes';
-import { getAPI, patchAPI, postAPI } from './utils/requestUtils';
+import { patchAPI, postAPI } from './utils/requestUtils';
-export interface NewDatabaseConnection {
+export interface NewConnection {
name: string;
db_name: string;
username: string;
@@ -10,10 +10,17 @@ export interface NewDatabaseConnection {
password: string;
}
-function add(connectionDetails: NewDatabaseConnection) {
+export type ConnectionUpdates = Partial>;
+
+function add(connectionDetails: NewConnection) {
return postAPI('/api/db/v0/databases/', connectionDetails);
}
+function update(databaseId: number, updates: ConnectionUpdates) {
+ return patchAPI(`/api/db/v0/databases/${databaseId}/`, updates);
+}
+
export default {
add,
+ update,
};
diff --git a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
index af9ae8f165..42ac87f3b0 100644
--- a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
+++ b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
@@ -48,7 +48,7 @@
use:active
>
- Add Database Connection
+ Database Connection
diff --git a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
index c29f524f0e..7257587c31 100644
--- a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
@@ -11,10 +11,14 @@
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';
- function handleSuccess(event: CustomEvent) {
+ async function handleSuccess(event: CustomEvent) {
const database = event.detail;
toast.success(`${database.name} connected successfully!`);
+ await reflectApi.reflect();
+ await reloadDatabases();
router.goto(getDatabasePageUrl(database.name));
}
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
index b378802cf2..5e463995bf 100644
--- a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
@@ -4,6 +4,7 @@
import {
FormSubmit,
makeForm,
+ optionalField,
requiredField,
} from '@mathesar/components/form';
import { databases } from '@mathesar/stores/databases';
@@ -26,7 +27,7 @@
$: connectionName = requiredField(database?.name ?? '');
$: databaseName = requiredField(database?.db_name ?? '');
- $: username = requiredField('');
+ $: username = requiredField(database?.username ?? '');
$: host = requiredField(database?.host ?? '');
$: port = requiredField(database?.port ?? '5432', [
(value) =>
@@ -34,7 +35,11 @@
? { type: 'valid' }
: { type: 'invalid', errorMsg: 'Port should be a valid number' },
]);
- $: password = requiredField('');
+
+ // There will be no prefill value even in the case of editing
+ $: password = isNewConnection ? requiredField('') : optionalField('');
+ $: hasPasswordChangedStore = password.hasChanges;
+ $: hasPasswordChanged = $hasPasswordChangedStore;
$: formFields = {
connectionName,
@@ -45,9 +50,9 @@
password,
};
$: form = makeForm(formFields);
+ $: ({ isSubmitting } = form);
async function addNewDatabaseConnection() {
- console.log('addNewDatabaseConnection');
const formValues = $form.values;
return await databaseConnectionApi.add({
name: formValues.connectionName,
@@ -59,11 +64,30 @@
});
}
+ async function updateDatabaseConnection() {
+ const formValues = $form.values;
+ if (database) {
+ return await databaseConnectionApi.update(database?.id, {
+ db_name: formValues.databaseName,
+ username: formValues.username,
+ host: formValues.host,
+ port: formValues.port,
+ ...(hasPasswordChanged ? { password: formValues.password } : undefined),
+ });
+ }
+ throw new Error(
+ '[updateDatabaseConnection] called but no database found to edit.',
+ );
+ }
+
async function saveConnectionDetails() {
- console.log('saveConnectionDetails', isNewConnection);
if (isNewConnection) {
const database = await addNewDatabaseConnection();
dispatch('create', database);
+ } else {
+ await updateDatabaseConnection();
+ form.reset();
+ dispatch('update');
}
}
@@ -95,7 +119,10 @@
@@ -128,11 +155,11 @@
/>
diff --git a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
index 447c1cf6a6..b83b33a13d 100644
--- a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
@@ -1,8 +1,21 @@
-Edit DB Connection for {databaseName}
+
+ Edit Database Connection
+
+
+
+
diff --git a/mathesar_ui/src/pages/database/ConnectionError.svelte b/mathesar_ui/src/pages/database/ConnectionError.svelte
new file mode 100644
index 0000000000..ff4a59372b
--- /dev/null
+++ b/mathesar_ui/src/pages/database/ConnectionError.svelte
@@ -0,0 +1,38 @@
+
+
+
+ Error connecting to the database
+
+
diff --git a/mathesar_ui/src/pages/database/DatabaseDetails.svelte b/mathesar_ui/src/pages/database/DatabaseDetails.svelte
index aad6f8c443..abdee66013 100644
--- a/mathesar_ui/src/pages/database/DatabaseDetails.svelte
+++ b/mathesar_ui/src/pages/database/DatabaseDetails.svelte
@@ -15,6 +15,7 @@
iconManageAccess,
iconRefresh,
iconMoreActions,
+ iconEdit,
} from '@mathesar/icons';
import { confirmDelete } from '@mathesar/stores/confirmation';
import { modal } from '@mathesar/stores/modal';
@@ -32,6 +33,9 @@
import DbAccessControlModal from './DbAccessControlModal.svelte';
import SchemaRow from './SchemaRow.svelte';
import { deleteSchemaConfirmationBody } from './__help__/databaseHelp';
+ import LinkMenuItem from '@mathesar/component-library/menu/LinkMenuItem.svelte';
+ import { getDatabaseConnectionEditUrl } from '@mathesar/routes/urls';
+ import ConnectionError from './ConnectionError.svelte';
const addEditModal = modal.spawnModalController();
const accessControlModal = modal.spawnModalController();
@@ -159,6 +163,12 @@
+
+ Edit Database Connection
+
{/if}
@@ -169,41 +179,46 @@
Schemas ({schemasMap.size})
-
-
- {#if canExecuteDDL}
-
- {/if}
-
-
- {labeledCount(displayList, 'results')}
- for all schemas matching
- {filterQuery}
-
-
- {#each displayList as schema (schema.id)}
- -
- editSchema(schema)}
- on:delete={() => deleteSchema(schema)}
- />
-
- {/each}
-
-
+
+ {#if schemasMap.size === 0}
+
+ {:else}
+
+
+ {#if canExecuteDDL}
+
+ {/if}
+
+
+ {labeledCount(displayList, 'results')}
+ for all schemas matching
+ {filterQuery}
+
+
+ {#each displayList as schema (schema.id)}
+ -
+ editSchema(schema)}
+ on:delete={() => deleteSchema(schema)}
+ />
+
+ {/each}
+
+
+ {/if}
+
+
-
-
+
+
From 5110a402e35e1a18327984f0c2e3f7276776a3d9 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Sat, 23 Sep 2023 01:19:06 +0530
Subject: [PATCH 021/111] delete database connection
---
mathesar_ui/src/api/databaseConnection.ts | 8 +-
.../src/pages/database/DatabaseDetails.svelte | 36 +++++++--
...DatabaseConnectionConfirmationModal.svelte | 75 +++++++++++++++++++
3 files changed, 112 insertions(+), 7 deletions(-)
create mode 100644 mathesar_ui/src/pages/database/DeleteDatabaseConnectionConfirmationModal.svelte
diff --git a/mathesar_ui/src/api/databaseConnection.ts b/mathesar_ui/src/api/databaseConnection.ts
index b36e2f61cf..7fb041e038 100644
--- a/mathesar_ui/src/api/databaseConnection.ts
+++ b/mathesar_ui/src/api/databaseConnection.ts
@@ -1,5 +1,5 @@
import type { Database } from '@mathesar/AppTypes';
-import { patchAPI, postAPI } from './utils/requestUtils';
+import { deleteAPI, patchAPI, postAPI } from './utils/requestUtils';
export interface NewConnection {
name: string;
@@ -20,7 +20,13 @@ function update(databaseId: number, updates: ConnectionUpdates) {
return patchAPI(`/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,
};
diff --git a/mathesar_ui/src/pages/database/DatabaseDetails.svelte b/mathesar_ui/src/pages/database/DatabaseDetails.svelte
index abdee66013..f79e1e89ee 100644
--- a/mathesar_ui/src/pages/database/DatabaseDetails.svelte
+++ b/mathesar_ui/src/pages/database/DatabaseDetails.svelte
@@ -16,6 +16,7 @@
iconRefresh,
iconMoreActions,
iconEdit,
+ iconDeleteMajor,
} from '@mathesar/icons';
import { confirmDelete } from '@mathesar/stores/confirmation';
import { modal } from '@mathesar/stores/modal';
@@ -36,9 +37,13 @@
import LinkMenuItem from '@mathesar/component-library/menu/LinkMenuItem.svelte';
import { getDatabaseConnectionEditUrl } from '@mathesar/routes/urls';
import ConnectionError from './ConnectionError.svelte';
+ import DeleteDatabaseConnectionConfirmationModal from './DeleteDatabaseConnectionConfirmationModal.svelte';
+ import { reloadDatabases } from '@mathesar/stores/databases';
+ import { router } from 'tinro';
const addEditModal = modal.spawnModalController();
const accessControlModal = modal.spawnModalController();
+ const deleteConnectionModal = modal.spawnModalController();
const userProfileStore = getUserProfileStoreFromContext();
$: userProfile = $userProfileStore;
@@ -114,6 +119,11 @@
isReflectionRunning = false;
}
}
+
+ async function handleSuccessfulDeleteConnection() {
+ await reloadDatabases();
+ router.goto('/');
+ }
-
- Edit Database Connection
-
+ {#if database.editable && userProfile?.isSuperUser}
+
+ Edit Database Connection
+
+
+ deleteConnectionModal.open()}
+ >
+ Delete Connection
+
+ {/if}
{/if}
@@ -228,6 +247,11 @@
/>
+
From ad09ba380418dfcab52ec6a4b6f2defb1d133b4c Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Sat, 23 Sep 2023 01:30:22 +0530
Subject: [PATCH 022/111] lint fixes
---
.../AddDatabaseConnection.svelte | 4 ++--
.../DatabaseConnectionForm.svelte | 16 ++++++++--------
.../EditDatabaseConnection.svelte | 4 ++--
.../src/pages/database/DatabaseDetails.svelte | 8 ++++----
...eteDatabaseConnectionConfirmationModal.svelte | 2 +-
5 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
index 7257587c31..ee3d147b72 100644
--- a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
@@ -1,9 +1,7 @@
-
+ Users
+
+
+
+
+
diff --git a/mathesar_ui/src/routes/AdminRoute.svelte b/mathesar_ui/src/routes/AdminRoute.svelte
index d6603458b3..024260e9da 100644
--- a/mathesar_ui/src/routes/AdminRoute.svelte
+++ b/mathesar_ui/src/routes/AdminRoute.svelte
@@ -31,6 +31,7 @@
From e7a9d1c0cff6f98f20818eec441587c5c1cfd9ff Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Tue, 26 Sep 2023 17:48:00 +0530
Subject: [PATCH 024/111] database connection list page & rounting
---
mathesar/urls.py | 1 +
mathesar/views.py | 7 ++
.../pages/admin-users/AdminNavigation.svelte | 76 +++++-------
.../AddDatabaseConnection.svelte | 11 +-
.../DatabaseConnectionItem.svelte | 77 ++++++++++++
.../DatabaseConnectionSkeleton.svelte | 16 +++
.../DatabaseConnectionsList.svelte | 116 ++++++++++++++++++
.../EditDatabaseConnection.svelte | 5 +-
.../src/pages/database/NoDatabaseFound.svelte | 0
.../src/routes/DatabaseConnectionRoute.svelte | 6 +-
mathesar_ui/src/routes/urls.ts | 3 +-
11 files changed, 264 insertions(+), 54 deletions(-)
create mode 100644 mathesar_ui/src/pages/database-connection/DatabaseConnectionItem.svelte
create mode 100644 mathesar_ui/src/pages/database-connection/DatabaseConnectionSkeleton.svelte
create mode 100644 mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
create mode 100644 mathesar_ui/src/pages/database/NoDatabaseFound.svelte
diff --git a/mathesar/urls.py b/mathesar/urls.py
index 734d097b7b..6b51b68d11 100644
--- a/mathesar/urls.py
+++ b/mathesar/urls.py
@@ -53,6 +53,7 @@
path('administration/users/', views.admin_home, name='admin_users_home'),
path('administration/users//', 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//', views.edit_database_connection, name='edit_database_connection'),
path('shares/tables//', views.shared_table, name='shared_table'),
diff --git a/mathesar/views.py b/mathesar/views.py
index aaa4689e21..1f56ac467e 100644
--- a/mathesar/views.py
+++ b/mathesar/views.py
@@ -288,6 +288,13 @@ 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', {
diff --git a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
index f81e5df608..55e485f215 100644
--- a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
+++ b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
@@ -1,20 +1,15 @@
diff --git a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
index ee3d147b72..a60bf7ea97 100644
--- a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
@@ -1,9 +1,8 @@
+
+
+ {#if !database.editable}
+
+
+
+ {:else}
+
+
+
+ {/if}
+ {database.name}
+ {database.db_name}
+
+
+
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionSkeleton.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionSkeleton.svelte
new file mode 100644
index 0000000000..ce0d043ff1
--- /dev/null
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionSkeleton.svelte
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
new file mode 100644
index 0000000000..8a0de1a6f9
--- /dev/null
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
@@ -0,0 +1,116 @@
+
+
+
+ {makeSimplePageTitle('Database Connections')}
+
+
+
+
+Database Connections {filteredConnectionsCountText}
+
+
+ {#if connectionsStatus === States.Loading && !isPreloaded}
+
+ {:else if connectionsStatus === States.Done || isPreloaded}
+
+
+
+
+ Add Database Connection
+
+
+
+
+ {labeledCount(filteredConnections, 'results')}
+ for all database connections matching {filterQuery}
+
+
+
+ {#if filteredConnections.length}
+
+ {#each filteredConnections as connection (connection.id)}
+
+ {/each}
+
+ {:else if connections.length === 0}
+ No database connection found
+ {/if}
+
+
+ {:else if connectionsStatus === States.Error}
+
+ Error: {connectionsError}
+
+ {/if}
+
+
+
diff --git a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
index 5cb32c7a66..7f9e274f0a 100644
--- a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
@@ -1,7 +1,6 @@
-
+
+
+
diff --git a/mathesar_ui/src/routes/urls.ts b/mathesar_ui/src/routes/urls.ts
index b3f8999260..e4fb4e285c 100644
--- a/mathesar_ui/src/routes/urls.ts
+++ b/mathesar_ui/src/routes/urls.ts
@@ -116,7 +116,8 @@ export const ADMIN_USERS_PAGE_ADD_NEW_URL = `${ADMIN_URL}users/new/`;
export const LOGOUT_URL = '/auth/logout/';
export const DATABASE_CONNECTION_SLUG = 'db-connection';
-export const ADD_DATABASE_CONNECTION_URL = `${ADMIN_URL}${DATABASE_CONNECTION_SLUG}/add/`;
+export const DATABASE_CONNECTION_LIST_URL = `${ADMIN_URL}${DATABASE_CONNECTION_SLUG}/`;
+export const DATABASE_CONNECTION_ADD_URL = `${ADMIN_URL}${DATABASE_CONNECTION_SLUG}/add/`;
export function getDatabaseConnectionEditUrl(databaseName: string) {
return `${ADMIN_URL}${DATABASE_CONNECTION_SLUG}/edit/${databaseName}/`;
From cce8e0c5ad78ae5bb65407713fbe12fd4c1d721d Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Wed, 27 Sep 2023 18:33:06 +0530
Subject: [PATCH 025/111] renamed user form component
---
.../form/GridFormInput.svelte} | 7 +++---
.../form/GridFormInputRow.svelte} | 0
.../DatabaseConnectionForm.svelte | 14 +++++------
.../PasswordChangeForm.svelte | 24 +++++++++----------
.../UserDetailsForm.svelte | 12 +++++-----
5 files changed, 29 insertions(+), 28 deletions(-)
rename mathesar_ui/src/{systems/users-and-permissions/UserFormInput.svelte => components/form/GridFormInput.svelte} (92%)
rename mathesar_ui/src/{systems/users-and-permissions/UserFormInputRow.svelte => components/form/GridFormInputRow.svelte} (100%)
diff --git a/mathesar_ui/src/systems/users-and-permissions/UserFormInput.svelte b/mathesar_ui/src/components/form/GridFormInput.svelte
similarity index 92%
rename from mathesar_ui/src/systems/users-and-permissions/UserFormInput.svelte
rename to mathesar_ui/src/components/form/GridFormInput.svelte
index 8e81a7eec3..c703cbb6ef 100644
--- a/mathesar_ui/src/systems/users-and-permissions/UserFormInput.svelte
+++ b/mathesar_ui/src/components/form/GridFormInput.svelte
@@ -1,4 +1,6 @@
-
+
{/if}
-
+
diff --git a/mathesar_ui/src/pages/database/NoDatabaseFound.svelte b/mathesar_ui/src/pages/database/NoDatabaseFound.svelte
index e69de29bb2..2be30e167a 100644
--- a/mathesar_ui/src/pages/database/NoDatabaseFound.svelte
+++ b/mathesar_ui/src/pages/database/NoDatabaseFound.svelte
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+ No Databases Found
+
+ Looks like you don't have any databases set up. You'll need to connect
+ to a database to start using Mathesar.
+
+
+ Add Database Connection
+
+
+
+
diff --git a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
index 2cda4b8970..e71ceec904 100644
--- a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
+++ b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
@@ -1,8 +1,8 @@
- import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+ import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+ } from '@mathesar/AppTypes';
import { iconSchema } from '@mathesar/icons';
import { getSchemaPageUrl } from '@mathesar/routes/urls';
import {
@@ -9,7 +12,7 @@
import BreadcrumbSelector from './BreadcrumbSelector.svelte';
import type { BreadcrumbSelectorEntry } from './breadcrumbTypes';
- export let database: Database;
+ export let database: SuccessfullyConnectedDatabase;
function makeBreadcrumbSelectorItem(
schemaEntry: SchemaEntry,
diff --git a/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts b/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts
index b18a6ea385..5af30bdbbf 100644
--- a/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts
+++ b/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts
@@ -1,6 +1,10 @@
import type { QueryInstance } from '@mathesar/api/types/queries';
import type { TableEntry } from '@mathesar/api/types/tables';
-import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+import type {
+ SuccessfullyConnectedDatabase,
+ Database,
+ SchemaEntry,
+} from '@mathesar/AppTypes';
import type {
ComponentAndProps,
IconProps,
@@ -13,13 +17,13 @@ export interface BreadcrumbItemDatabase {
export interface BreadcrumbItemSchema {
type: 'schema';
- database: Database;
+ database: SuccessfullyConnectedDatabase;
schema: SchemaEntry;
}
export interface BreadcrumbItemTable {
type: 'table';
- database: Database;
+ database: SuccessfullyConnectedDatabase;
schema: SchemaEntry;
table: TableEntry;
}
@@ -33,7 +37,7 @@ export interface BreadcrumbItemSimple {
export interface BreadcrumbItemRecord {
type: 'record';
- database: Database;
+ database: SuccessfullyConnectedDatabase;
schema: SchemaEntry;
table: TableEntry;
record: {
@@ -44,7 +48,7 @@ export interface BreadcrumbItemRecord {
export interface BreadcrumbItemExploration {
type: 'exploration';
- database: Database;
+ database: SuccessfullyConnectedDatabase;
schema: SchemaEntry;
query: Pick;
}
diff --git a/mathesar_ui/src/components/form/GridFormInput.svelte b/mathesar_ui/src/components/form/GridFormInput.svelte
index c703cbb6ef..da1ad30793 100644
--- a/mathesar_ui/src/components/form/GridFormInput.svelte
+++ b/mathesar_ui/src/components/form/GridFormInput.svelte
@@ -1,6 +1,5 @@
diff --git a/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte b/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte
index 1f7dee9b77..4ef4dd0fb2 100644
--- a/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte
+++ b/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte
@@ -1,7 +1,10 @@
diff --git a/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte b/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte
index 9d9918bccd..fc7321eda3 100644
--- a/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte
+++ b/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte
@@ -2,7 +2,10 @@
import { router } from 'tinro';
import { createTable } from '@mathesar/stores/tables';
import { getImportPageUrl, getTablePageUrl } from '@mathesar/routes/urls';
- import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+ import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+ } from '@mathesar/AppTypes';
import {
DropdownMenu,
Spinner,
@@ -12,7 +15,7 @@
import Icon from '@mathesar/component-library/icon/Icon.svelte';
import LinkMenuItem from '@mathesar/component-library/menu/LinkMenuItem.svelte';
- export let database: Database;
+ export let database: SuccessfullyConnectedDatabase;
export let schema: SchemaEntry;
let isCreatingNewTable = false;
diff --git a/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte b/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte
index 2e1548783c..bbec045111 100644
--- a/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte
+++ b/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte
@@ -1,10 +1,13 @@
diff --git a/mathesar_ui/src/pages/schema/ExplorationItem.svelte b/mathesar_ui/src/pages/schema/ExplorationItem.svelte
index 96080462e1..5cf8aa7a2e 100644
--- a/mathesar_ui/src/pages/schema/ExplorationItem.svelte
+++ b/mathesar_ui/src/pages/schema/ExplorationItem.svelte
@@ -5,10 +5,13 @@
import { iconExploration } from '@mathesar/icons';
import { getExplorationPageUrl } from '@mathesar/routes/urls';
import { tables as tablesStore } from '@mathesar/stores/tables';
- import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+ import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+ } from '@mathesar/AppTypes';
export let exploration: QueryInstance;
- export let database: Database;
+ export let database: SuccessfullyConnectedDatabase;
export let schema: SchemaEntry;
$: baseTable = $tablesStore.data.get(exploration.base_table);
diff --git a/mathesar_ui/src/pages/schema/ExplorationsList.svelte b/mathesar_ui/src/pages/schema/ExplorationsList.svelte
index e900014e42..6980414a10 100644
--- a/mathesar_ui/src/pages/schema/ExplorationsList.svelte
+++ b/mathesar_ui/src/pages/schema/ExplorationsList.svelte
@@ -1,12 +1,15 @@
diff --git a/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte b/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte
index d4224c7d9d..7fb5e31a81 100644
--- a/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte
+++ b/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte
@@ -3,7 +3,10 @@
ControlledModal,
type ModalController,
} from '@mathesar-component-library';
- import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+ import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+ } from '@mathesar/AppTypes';
import Identifier from '@mathesar/components/Identifier.svelte';
import {
setUsersStoreInContext,
@@ -15,7 +18,7 @@
import type { ObjectRoleMap } from '@mathesar/utils/permissions';
export let controller: ModalController;
- export let database: Database;
+ export let database: SuccessfullyConnectedDatabase;
export let schema: SchemaEntry;
const usersStore = setUsersStoreInContext();
diff --git a/mathesar_ui/src/pages/schema/SchemaExplorations.svelte b/mathesar_ui/src/pages/schema/SchemaExplorations.svelte
index 263e4a7692..9016768f9a 100644
--- a/mathesar_ui/src/pages/schema/SchemaExplorations.svelte
+++ b/mathesar_ui/src/pages/schema/SchemaExplorations.svelte
@@ -1,6 +1,9 @@
diff --git a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
index e71ceec904..c9da932132 100644
--- a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
+++ b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
@@ -11,7 +11,7 @@
const userProfileStore = getUserProfileStoreFromContext();
$: userProfile = $userProfileStore;
- $: firstDatabase = $databases.data?.[0];
+ $: firstDatabase = $databases.successfulConnections?.[0];
{#if firstDatabase}
diff --git a/mathesar_ui/src/routes/DataExplorerRoute.svelte b/mathesar_ui/src/routes/DataExplorerRoute.svelte
index be960e6bce..75d2d69c60 100644
--- a/mathesar_ui/src/routes/DataExplorerRoute.svelte
+++ b/mathesar_ui/src/routes/DataExplorerRoute.svelte
@@ -1,6 +1,9 @@
diff --git a/mathesar_ui/src/routes/RecordPageRoute.svelte b/mathesar_ui/src/routes/RecordPageRoute.svelte
index eecccf3d51..2c653e5a5b 100644
--- a/mathesar_ui/src/routes/RecordPageRoute.svelte
+++ b/mathesar_ui/src/routes/RecordPageRoute.svelte
@@ -2,10 +2,13 @@
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
import RecordPage from '@mathesar/pages/record/RecordPage.svelte';
import type { TableEntry } from '@mathesar/api/types/tables';
- import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+ import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+ } from '@mathesar/AppTypes';
import RecordStore from '@mathesar/pages/record/RecordStore';
- export let database: Database;
+ export let database: SuccessfullyConnectedDatabase;
export let schema: SchemaEntry;
export let table: TableEntry;
export let recordPk: string;
diff --git a/mathesar_ui/src/routes/SchemaRoute.svelte b/mathesar_ui/src/routes/SchemaRoute.svelte
index 164449b2d7..a863a3be45 100644
--- a/mathesar_ui/src/routes/SchemaRoute.svelte
+++ b/mathesar_ui/src/routes/SchemaRoute.svelte
@@ -2,7 +2,7 @@
import { onMount } from 'svelte';
import { Route } from 'tinro';
- import type { Database } from '@mathesar/AppTypes';
+ import type { SuccessfullyConnectedDatabase } from '@mathesar/AppTypes';
import ErrorPage from '@mathesar/pages/ErrorPage.svelte';
import SchemaPage from '@mathesar/pages/schema/SchemaPage.svelte';
import { currentSchemaId, schemas } from '@mathesar/stores/schemas';
@@ -16,7 +16,7 @@
const userProfile = getUserProfileStoreFromContext();
- export let database: Database;
+ export let database: SuccessfullyConnectedDatabase;
export let schemaId: number;
$: $currentSchemaId = schemaId;
diff --git a/mathesar_ui/src/routes/TableRoute.svelte b/mathesar_ui/src/routes/TableRoute.svelte
index 2d68876158..e13a1de0cd 100644
--- a/mathesar_ui/src/routes/TableRoute.svelte
+++ b/mathesar_ui/src/routes/TableRoute.svelte
@@ -2,14 +2,17 @@
import { onMount } from 'svelte';
import { Route } from 'tinro';
- import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+ import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+ } from '@mathesar/AppTypes';
import ErrorPage from '@mathesar/pages/ErrorPage.svelte';
import TablePage from '@mathesar/pages/table/TablePage.svelte';
import { currentTableId, tables } from '@mathesar/stores/tables';
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
import RecordPageRoute from './RecordPageRoute.svelte';
- export let database: Database;
+ export let database: SuccessfullyConnectedDatabase;
export let schema: SchemaEntry;
export let tableId: number;
diff --git a/mathesar_ui/src/stores/abstract-types/store.ts b/mathesar_ui/src/stores/abstract-types/store.ts
index ee9a8cf9bc..84f05fe7bd 100644
--- a/mathesar_ui/src/stores/abstract-types/store.ts
+++ b/mathesar_ui/src/stores/abstract-types/store.ts
@@ -4,7 +4,7 @@ import { currentDatabase } from '@mathesar/stores/databases';
import { preloadCommonData } from '@mathesar/utils/preloadData';
import type { Readable, Writable, Unsubscriber } from 'svelte/store';
-import type { Database } from '@mathesar/AppTypes';
+import type { SuccessfullyConnectedDatabase } from '@mathesar/AppTypes';
import type { CancellablePromise } from '@mathesar-component-library';
import type {
AbstractTypesMap,
@@ -17,16 +17,16 @@ import { constructAbstractTypeMapFromResponse } from './abstractTypeCategories';
const commonData = preloadCommonData();
const databasesToAbstractTypesStoreMap: Map<
- Database['id'],
+ SuccessfullyConnectedDatabase['id'],
Writable
> = new Map();
const abstractTypesRequestMap: Map<
- Database['id'],
+ SuccessfullyConnectedDatabase['id'],
CancellablePromise
> = new Map();
export async function refetchTypesForDb(
- databaseId: Database['id'],
+ databaseId: SuccessfullyConnectedDatabase['id'],
): Promise {
const store = databasesToAbstractTypesStoreMap.get(databaseId);
if (!store) {
@@ -75,7 +75,7 @@ export async function refetchTypesForDb(
let preload = true;
function getTypesForDatabase(
- database: Database,
+ database: SuccessfullyConnectedDatabase,
): Writable {
let store = databasesToAbstractTypesStoreMap.get(database.id);
if (!store) {
diff --git a/mathesar_ui/src/stores/databases.ts b/mathesar_ui/src/stores/databases.ts
index 649733d8ca..377d320a45 100644
--- a/mathesar_ui/src/stores/databases.ts
+++ b/mathesar_ui/src/stores/databases.ts
@@ -1,37 +1,48 @@
import { writable, derived } from 'svelte/store';
-import { preloadCommonData } from '@mathesar/utils/preloadData';
+import {
+ isSuccessfullyConnectedDatabase,
+ preloadCommonData,
+} from '@mathesar/utils/preloadData';
import databaseApi from '@mathesar/api/databases';
import { States } from '@mathesar/api/utils/requestUtils';
import type { Writable } from 'svelte/store';
-import type { Database } from '@mathesar/AppTypes';
+import type {
+ SuccessfullyConnectedDatabase,
+ Database,
+} from '@mathesar/AppTypes';
import type { PaginatedResponse } from '@mathesar/api/utils/requestUtils';
import type { CancellablePromise } from '@mathesar-component-library';
const commonData = preloadCommonData();
-export const currentDBName: Writable = writable(
- commonData?.current_db ?? undefined,
-);
+export const currentDBName: Writable<
+ SuccessfullyConnectedDatabase['name'] | undefined
+> = writable(commonData?.current_db ?? undefined);
export interface DatabaseStoreData {
preload?: boolean;
state: States;
data: Database[];
error?: string;
+ successfulConnections: SuccessfullyConnectedDatabase[];
}
export const databases = writable({
preload: true,
state: States.Loading,
data: commonData?.databases ?? [],
+ successfulConnections: (commonData?.databases ?? []).filter(
+ (database): database is SuccessfullyConnectedDatabase =>
+ !('error' in database),
+ ),
});
export const currentDatabase = derived(
[currentDBName, databases],
([_currentDBName, databasesStore]) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
- const _databases = databasesStore.data;
+ const _databases = databasesStore.successfulConnections;
if (!_databases?.length) {
return undefined;
}
@@ -54,14 +65,17 @@ export async function reloadDatabases(): Promise<
databaseRequest = databaseApi.list();
const response = await databaseRequest;
const data = response.results || [];
+ const successDatabases = data.filter(isSuccessfullyConnectedDatabase);
databases.set({
state: States.Done,
data,
+ successfulConnections: successDatabases,
});
return response;
} catch (err) {
databases.set({
data: [],
+ successfulConnections: [],
state: States.Error,
error: err instanceof Error ? err.message : undefined,
});
diff --git a/mathesar_ui/src/stores/schemas.ts b/mathesar_ui/src/stores/schemas.ts
index f860c27cb7..01639be86c 100644
--- a/mathesar_ui/src/stores/schemas.ts
+++ b/mathesar_ui/src/stores/schemas.ts
@@ -11,7 +11,11 @@ import {
} from '@mathesar/api/utils/requestUtils';
import type { PaginatedResponse } from '@mathesar/api/utils/requestUtils';
-import type { Database, SchemaEntry, SchemaResponse } from '@mathesar/AppTypes';
+import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+ SchemaResponse,
+} from '@mathesar/AppTypes';
import type { CancellablePromise } from '@mathesar-component-library';
import { currentDBName } from './databases';
@@ -28,11 +32,11 @@ export interface DBSchemaStoreData {
}
const dbSchemaStoreMap: Map<
- Database['name'],
+ SuccessfullyConnectedDatabase['name'],
Writable
> = new Map();
const dbSchemasRequestMap: Map<
- Database['name'],
+ SuccessfullyConnectedDatabase['name'],
CancellablePromise | undefined>
> = new Map();
@@ -43,7 +47,7 @@ function findStoreBySchemaId(id: SchemaEntry['id']) {
}
function setDBSchemaStore(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schemas: SchemaResponse[],
): Writable {
const schemaMap: DBSchemaStoreData['data'] = new Map();
@@ -67,7 +71,7 @@ function setDBSchemaStore(
}
function updateSchemaInDBSchemaStore(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schema: SchemaResponse,
) {
const store = dbSchemaStoreMap.get(database);
@@ -83,7 +87,7 @@ function updateSchemaInDBSchemaStore(
}
function removeSchemaInDBSchemaStore(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schemaId: SchemaEntry['id'],
) {
const store = dbSchemaStoreMap.get(database);
@@ -99,7 +103,7 @@ function removeSchemaInDBSchemaStore(
}
export function addCountToSchemaNumTables(
- database: Database,
+ database: SuccessfullyConnectedDatabase,
schema: SchemaEntry,
count: number,
) {
@@ -140,7 +144,7 @@ export function addCountToSchemaNumExplorations(
}
export async function refetchSchemasForDB(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
): Promise {
const store = dbSchemaStoreMap.get(database);
if (!store) {
@@ -177,7 +181,7 @@ export async function refetchSchemasForDB(
}
export async function refetchSchema(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schemaId: SchemaEntry['id'],
): Promise {
const store = dbSchemaStoreMap.get(database);
@@ -203,7 +207,7 @@ export async function refetchSchema(
let preload = true;
export function getSchemasStoreForDB(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
): Writable {
let store = dbSchemaStoreMap.get(database);
if (!store) {
@@ -225,7 +229,7 @@ export function getSchemasStoreForDB(
}
export function getSchemaInfo(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schemaId: SchemaEntry['id'],
): SchemaEntry | undefined {
const store = dbSchemaStoreMap.get(database);
@@ -236,7 +240,7 @@ export function getSchemaInfo(
}
export async function createSchema(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schemaName: SchemaEntry['name'],
schemaDescription: SchemaEntry['description'],
): Promise {
@@ -250,7 +254,7 @@ export async function createSchema(
}
export async function updateSchema(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schema: SchemaEntry,
): Promise {
const url = `/api/db/v0/schemas/${schema.id}/`;
@@ -263,7 +267,7 @@ export async function updateSchema(
}
export async function deleteSchema(
- database: Database['name'],
+ database: SuccessfullyConnectedDatabase['name'],
schemaId: SchemaEntry['id'],
): Promise {
await deleteAPI(`/api/db/v0/schemas/${schemaId}/`);
diff --git a/mathesar_ui/src/stores/tables.ts b/mathesar_ui/src/stores/tables.ts
index a8a21d8bf9..6f39bc45c5 100644
--- a/mathesar_ui/src/stores/tables.ts
+++ b/mathesar_ui/src/stores/tables.ts
@@ -28,7 +28,11 @@ import type {
SplitTableRequest,
SplitTableResponse,
} from '@mathesar/api/types/tables/split_table';
-import type { DBObjectEntry, Database, SchemaEntry } from '@mathesar/AppTypes';
+import type {
+ DBObjectEntry,
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+} from '@mathesar/AppTypes';
import { invalidIf } from '@mathesar/components/form';
import type { PaginatedResponse } from '@mathesar/api/utils/requestUtils';
import {
@@ -189,7 +193,7 @@ function findAndUpdateTableStore(id: TableEntry['id'], tableEntry: TableEntry) {
}
export function deleteTable(
- database: Database,
+ database: SuccessfullyConnectedDatabase,
schema: SchemaEntry,
tableId: TableEntry['id'],
): CancellablePromise {
@@ -236,7 +240,7 @@ export function updateTableMetaData(
}
export function createTable(
- database: Database,
+ database: SuccessfullyConnectedDatabase,
schema: SchemaEntry,
tableArgs: {
name?: string;
diff --git a/mathesar_ui/src/stores/users.ts b/mathesar_ui/src/stores/users.ts
index 73eca377c5..8af77df9e0 100644
--- a/mathesar_ui/src/stores/users.ts
+++ b/mathesar_ui/src/stores/users.ts
@@ -12,7 +12,10 @@ import userApi, {
import type { RequestStatus } from '@mathesar/api/utils/requestUtils';
import { getErrorMessage } from '@mathesar/utils/errors';
import type { MakeWritablePropertiesReadable } from '@mathesar/utils/typeUtils';
-import type { Database, SchemaEntry } from '@mathesar/AppTypes';
+import type {
+ SuccessfullyConnectedDatabase,
+ SchemaEntry,
+} from '@mathesar/AppTypes';
import {
rolesAllowOperation,
type AccessOperation,
@@ -49,7 +52,7 @@ export class UserModel {
hasPermission(
dbObject: {
- database?: Pick;
+ database?: Pick;
schema?: Pick;
},
operation: AccessOperation,
@@ -79,7 +82,7 @@ export class UserModel {
return rolesAllowOperation(operation, roles);
}
- getRoleForDb(database: Pick) {
+ getRoleForDb(database: Pick) {
return this.databaseRoles.get(database.id);
}
@@ -87,11 +90,11 @@ export class UserModel {
return this.schemaRoles.get(schema.id);
}
- hasDirectDbAccess(database: Pick) {
+ hasDirectDbAccess(database: Pick) {
return this.databaseRoles.has(database.id);
}
- hasDbAccess(database: Pick) {
+ hasDbAccess(database: Pick) {
return this.hasDirectDbAccess(database) || this.isSuperUser;
}
@@ -100,7 +103,7 @@ export class UserModel {
}
hasSchemaAccess(
- database: Pick,
+ database: Pick,
schema: Pick,
) {
return this.hasDbAccess(database) || this.hasDirectSchemaAccess(schema);
@@ -255,7 +258,7 @@ class WritableUsersStore {
async addDatabaseRoleForUser(
userId: number,
- database: Pick,
+ database: Pick,
role: UserRole,
) {
const dbRole = await userApi.addDatabaseRole(userId, database.id, role);
@@ -272,7 +275,7 @@ class WritableUsersStore {
async removeDatabaseAccessForUser(
userId: number,
- database: Pick,
+ database: Pick,
) {
const user = get(this.users).find((entry) => entry.id === userId);
const dbRole = user?.getRoleForDb(database);
@@ -327,13 +330,15 @@ class WritableUsersStore {
}
}
- getUsersWithAccessToDb(database: Pick) {
+ getUsersWithAccessToDb(database: Pick) {
return derived(this.users, ($users) =>
$users.filter((user) => user.hasDbAccess(database)),
);
}
- getUsersWithoutAccessToDb(database: Pick) {
+ getUsersWithoutAccessToDb(
+ database: Pick,
+ ) {
return derived(this.users, ($users) =>
$users.filter((user) => !user.hasDbAccess(database)),
);
@@ -356,7 +361,7 @@ class WritableUsersStore {
}
getUsersWithAccessToSchema(
- database: Pick,
+ database: Pick,
schema: Pick,
) {
return derived(this.users, ($users) =>
diff --git a/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte b/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte
index f22197cef5..9789658696 100644
--- a/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte
+++ b/mathesar_ui/src/systems/users-and-permissions/UserDetailsForm.svelte
@@ -21,8 +21,8 @@
} from '@mathesar/components/form';
import { iconSave, iconUndo } from '@mathesar/icons';
import { getUserProfileStoreFromContext } from '@mathesar/stores/userProfile';
- import SelectUserType from './SelectUserType.svelte';
import GridFormInput from '@mathesar/components/form/GridFormInput.svelte';
+ import SelectUserType from './SelectUserType.svelte';
const dispatch = createEventDispatcher<{ create: User; update: undefined }>();
const userProfileStore = getUserProfileStoreFromContext();
diff --git a/mathesar_ui/src/utils/preloadData.ts b/mathesar_ui/src/utils/preloadData.ts
index 1fbe7e567e..8ee0a2b8ef 100644
--- a/mathesar_ui/src/utils/preloadData.ts
+++ b/mathesar_ui/src/utils/preloadData.ts
@@ -1,7 +1,8 @@
import type {
- Database,
+ SuccessfullyConnectedDatabase,
SchemaResponse,
AbstractTypeResponse,
+ Database,
} from '@mathesar/AppTypes';
import type { TableEntry } from '@mathesar/api/types/tables';
import type { QueryInstance } from '@mathesar/api/types/queries';
@@ -43,3 +44,7 @@ export function preloadRouteData(routeName: string): T | undefined {
export function preloadCommonData(): CommonData | undefined {
return getData('#common-data');
}
+
+export const isSuccessfullyConnectedDatabase = (
+ database: Database,
+): database is SuccessfullyConnectedDatabase => !('error' in database);
From 7c12f77b013750c205d88c206538a1a0b6c36a76 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Mon, 2 Oct 2023 23:16:12 +0530
Subject: [PATCH 028/111] renamed connections list vars
---
.../DatabaseConnectionsList.svelte | 46 +++++++++----------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
index b21eb86a3b..699eaaa89c 100644
--- a/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
@@ -20,24 +20,24 @@
let filterQuery = '';
$: isPreloaded = $databases.preload;
- $: connections = $databases.data;
- $: connectionsStatus = $databases.state;
- $: connectionsError = $databases.error;
+ $: allDatabases = $databases.data;
+ $: databasesLoadStatus = $databases.state;
+ $: databasesLoadError = $databases.error;
- function filterConnections(_connections: Database[], query: string) {
- function isMatch(connection: Database, q: string) {
- if (!isSuccessfullyConnectedDatabase(connection)) {
- return connection.name.toLowerCase().includes(q);
+ function filterDatabase(_databases: Database[], query: string) {
+ function isMatch(database: Database, q: string) {
+ if (!isSuccessfullyConnectedDatabase(database)) {
+ return database.name.toLowerCase().includes(q);
}
return (
- connection.name.toLowerCase().includes(q) ||
- connection.db_name.toLowerCase().includes(q)
+ database.name.toLowerCase().includes(q) ||
+ database.db_name.toLowerCase().includes(q)
);
}
- return _connections.filter((connection) => {
+ return _databases.filter((database) => {
if (query) {
const sanitizedQuery = query.trim().toLowerCase();
- return isMatch(connection, sanitizedQuery);
+ return isMatch(database, sanitizedQuery);
}
return true;
});
@@ -47,9 +47,9 @@
filterQuery = '';
}
- $: filteredConnections = filterConnections(connections ?? [], filterQuery);
- $: filteredConnectionsCountText = filteredConnections.length
- ? `(${filteredConnections.length})`
+ $: filteredDatabases = filterDatabase(allDatabases ?? [], filterQuery);
+ $: filteredDatabasesCountText = filteredDatabases.length
+ ? `(${filteredDatabases.length})`
: '';
@@ -66,12 +66,12 @@
}}
/>
-Database Connections {filteredConnectionsCountText}
+Database Connections {filteredDatabasesCountText}
- {#if connectionsStatus === States.Loading && !isPreloaded}
+ {#if databasesLoadStatus === States.Loading && !isPreloaded}
- {:else if connectionsStatus === States.Done || isPreloaded}
+ {:else if databasesLoadStatus === States.Done || isPreloaded}
- {labeledCount(filteredConnections, 'results')}
+ {labeledCount(filteredDatabases, 'results')}
for all database connections matching {filterQuery}
- {#if filteredConnections.length}
+ {#if filteredDatabases.length}
- {#each filteredConnections as connection (connection.id)}
+ {#each filteredDatabases as connection (connection.id)}
{/each}
- {:else if connections.length === 0}
+ {:else if allDatabases.length === 0}
No database connection found
{/if}
- {:else if connectionsStatus === States.Error}
+ {:else if databasesLoadStatus === States.Error}
- Error: {connectionsError}
+ Error: {databasesLoadError}
{/if}
From fea9634406fbd2b762bfd8e8abc8f0933d82e8b2 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Mon, 2 Oct 2023 23:43:12 +0530
Subject: [PATCH 029/111] lint fixes
---
.../src/pages/database/DatabaseNavigationList.svelte | 2 +-
mathesar_ui/src/stores/databases.ts | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/mathesar_ui/src/pages/database/DatabaseNavigationList.svelte b/mathesar_ui/src/pages/database/DatabaseNavigationList.svelte
index 8ab1a84d10..a469373a75 100644
--- a/mathesar_ui/src/pages/database/DatabaseNavigationList.svelte
+++ b/mathesar_ui/src/pages/database/DatabaseNavigationList.svelte
@@ -25,7 +25,7 @@
To add or remove databases, visit the
- Add Database Configuration
+ Add Database Connection
section of mathesar.
diff --git a/mathesar_ui/src/stores/databases.ts b/mathesar_ui/src/stores/databases.ts
index 377d320a45..abbf40592c 100644
--- a/mathesar_ui/src/stores/databases.ts
+++ b/mathesar_ui/src/stores/databases.ts
@@ -16,9 +16,9 @@ import type { CancellablePromise } from '@mathesar-component-library';
const commonData = preloadCommonData();
-export const currentDBName: Writable<
- SuccessfullyConnectedDatabase['name'] | undefined
-> = writable(commonData?.current_db ?? undefined);
+export const currentDBName: Writable = writable(
+ commonData?.current_db ?? undefined,
+);
export interface DatabaseStoreData {
preload?: boolean;
From 8c194d4104cc1e7b1828f147b25af67d78c1a639 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Tue, 3 Oct 2023 00:26:28 +0530
Subject: [PATCH 030/111] user flow bug fixes
---
mathesar/views.py | 4 +++
mathesar_ui/src/AppTypes.ts | 18 ++++++------
.../src/components/form/GridFormInput.svelte | 1 -
.../AddDatabaseConnection.svelte | 2 ++
.../DatabaseConnectionForm.svelte | 29 ++++---------------
.../EditDatabaseConnection.svelte | 9 +++++-
6 files changed, 28 insertions(+), 35 deletions(-)
diff --git a/mathesar/views.py b/mathesar/views.py
index 30e8ae96de..0b9e548f92 100644
--- a/mathesar/views.py
+++ b/mathesar/views.py
@@ -81,7 +81,11 @@ def get_database_list(request):
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'
})
diff --git a/mathesar_ui/src/AppTypes.ts b/mathesar_ui/src/AppTypes.ts
index 0fec35df67..b636863b66 100644
--- a/mathesar_ui/src/AppTypes.ts
+++ b/mathesar_ui/src/AppTypes.ts
@@ -1,22 +1,22 @@
import type { TreeItem } from '@mathesar-component-library/types';
-export interface DatabaseWithConnectionError {
+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 {
- id: number;
- name: string;
+export interface SuccessfullyConnectedDatabase extends BaseDatabase {
deleted: boolean;
supported_types: string[];
- db_name: string;
- editable: boolean;
- username: string;
- host: string;
- port: string;
}
export type Database =
diff --git a/mathesar_ui/src/components/form/GridFormInput.svelte b/mathesar_ui/src/components/form/GridFormInput.svelte
index da1ad30793..a32c604bcf 100644
--- a/mathesar_ui/src/components/form/GridFormInput.svelte
+++ b/mathesar_ui/src/components/form/GridFormInput.svelte
@@ -1,5 +1,4 @@
From 070bd90ee883a2e3fd8ed29bbb597dcebbe52aff Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Tue, 3 Oct 2023 00:44:03 +0530
Subject: [PATCH 031/111] lint fixes
---
.../pages/database-connection/AddDatabaseConnection.svelte | 2 +-
.../pages/database-connection/DatabaseConnectionForm.svelte | 1 -
.../pages/database-connection/EditDatabaseConnection.svelte | 4 ++--
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
index ddb6972081..807033078d 100644
--- a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
@@ -9,9 +9,9 @@
import type { SuccessfullyConnectedDatabase } from '@mathesar/AppTypes';
import { router } from 'tinro';
import { reloadDatabases } from '@mathesar/stores/databases';
+ import { reflectApi } from '@mathesar/api/reflect';
import FormBox from '../admin-users/FormBox.svelte';
import DatabaseConnectionForm from './DatabaseConnectionForm.svelte';
- import { reflectApi } from '@mathesar/api/reflect';
async function handleSuccess(
event: CustomEvent,
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
index 647e565f1f..9da879acab 100644
--- a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
@@ -13,7 +13,6 @@
import { createEventDispatcher } from 'svelte';
import { extractDetailedFieldBasedErrors } from '@mathesar/api/utils/errors';
import WarningBox from '@mathesar/components/message-boxes/WarningBox.svelte';
- import { isSuccessfullyConnectedDatabase } from '@mathesar/utils/preloadData';
const dispatch = createEventDispatcher<{
create: SuccessfullyConnectedDatabase;
diff --git a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
index 9f2329f641..09791aebd3 100644
--- a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
@@ -7,10 +7,10 @@
getDatabasePageUrl,
} from '@mathesar/routes/urls';
import { reloadDatabases } from '@mathesar/stores/databases';
- import FormBox from '../admin-users/FormBox.svelte';
- import DatabaseConnectionForm from './DatabaseConnectionForm.svelte';
import { reflectApi } from '@mathesar/api/reflect';
import { router } from 'tinro';
+ import FormBox from '../admin-users/FormBox.svelte';
+ import DatabaseConnectionForm from './DatabaseConnectionForm.svelte';
export let databaseName: string;
From 668f922def5c0e534b5b0ea70f61c2b2b270d37c Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Tue, 3 Oct 2023 00:46:29 +0530
Subject: [PATCH 032/111] removed todos
---
mathesar_ui/src/pages/database/AddEditSchemaModal.svelte | 1 -
mathesar_ui/src/pages/database/DatabaseDetails.svelte | 1 -
2 files changed, 2 deletions(-)
diff --git a/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte b/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte
index 4ef4dd0fb2..604ed63711 100644
--- a/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte
+++ b/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte
@@ -1,4 +1,3 @@
-
- import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
- } from '@mathesar/AppTypes';
+ import type { Database, SchemaEntry } from '@mathesar/AppTypes';
import { iconSchema } from '@mathesar/icons';
import { getSchemaPageUrl } from '@mathesar/routes/urls';
import {
@@ -12,7 +9,7 @@
import BreadcrumbSelector from './BreadcrumbSelector.svelte';
import type { BreadcrumbSelectorEntry } from './breadcrumbTypes';
- export let database: SuccessfullyConnectedDatabase;
+ export let database: Database;
function makeBreadcrumbSelectorItem(
schemaEntry: SchemaEntry,
diff --git a/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts b/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts
index 5af30bdbbf..b18a6ea385 100644
--- a/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts
+++ b/mathesar_ui/src/components/breadcrumb/breadcrumbTypes.ts
@@ -1,10 +1,6 @@
import type { QueryInstance } from '@mathesar/api/types/queries';
import type { TableEntry } from '@mathesar/api/types/tables';
-import type {
- SuccessfullyConnectedDatabase,
- Database,
- SchemaEntry,
-} from '@mathesar/AppTypes';
+import type { Database, SchemaEntry } from '@mathesar/AppTypes';
import type {
ComponentAndProps,
IconProps,
@@ -17,13 +13,13 @@ export interface BreadcrumbItemDatabase {
export interface BreadcrumbItemSchema {
type: 'schema';
- database: SuccessfullyConnectedDatabase;
+ database: Database;
schema: SchemaEntry;
}
export interface BreadcrumbItemTable {
type: 'table';
- database: SuccessfullyConnectedDatabase;
+ database: Database;
schema: SchemaEntry;
table: TableEntry;
}
@@ -37,7 +33,7 @@ export interface BreadcrumbItemSimple {
export interface BreadcrumbItemRecord {
type: 'record';
- database: SuccessfullyConnectedDatabase;
+ database: Database;
schema: SchemaEntry;
table: TableEntry;
record: {
@@ -48,7 +44,7 @@ export interface BreadcrumbItemRecord {
export interface BreadcrumbItemExploration {
type: 'exploration';
- database: SuccessfullyConnectedDatabase;
+ database: Database;
schema: SchemaEntry;
query: Pick;
}
diff --git a/mathesar_ui/src/pages/data-explorer/DataExplorerPage.svelte b/mathesar_ui/src/pages/data-explorer/DataExplorerPage.svelte
index 9da414a031..6897eb592c 100644
--- a/mathesar_ui/src/pages/data-explorer/DataExplorerPage.svelte
+++ b/mathesar_ui/src/pages/data-explorer/DataExplorerPage.svelte
@@ -1,9 +1,6 @@
diff --git a/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte b/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte
index fc7321eda3..9d9918bccd 100644
--- a/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte
+++ b/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte
@@ -2,10 +2,7 @@
import { router } from 'tinro';
import { createTable } from '@mathesar/stores/tables';
import { getImportPageUrl, getTablePageUrl } from '@mathesar/routes/urls';
- import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
- } from '@mathesar/AppTypes';
+ import type { Database, SchemaEntry } from '@mathesar/AppTypes';
import {
DropdownMenu,
Spinner,
@@ -15,7 +12,7 @@
import Icon from '@mathesar/component-library/icon/Icon.svelte';
import LinkMenuItem from '@mathesar/component-library/menu/LinkMenuItem.svelte';
- export let database: SuccessfullyConnectedDatabase;
+ export let database: Database;
export let schema: SchemaEntry;
let isCreatingNewTable = false;
diff --git a/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte b/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte
index bbec045111..2e1548783c 100644
--- a/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte
+++ b/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte
@@ -1,13 +1,10 @@
diff --git a/mathesar_ui/src/pages/schema/ExplorationItem.svelte b/mathesar_ui/src/pages/schema/ExplorationItem.svelte
index 5cf8aa7a2e..96080462e1 100644
--- a/mathesar_ui/src/pages/schema/ExplorationItem.svelte
+++ b/mathesar_ui/src/pages/schema/ExplorationItem.svelte
@@ -5,13 +5,10 @@
import { iconExploration } from '@mathesar/icons';
import { getExplorationPageUrl } from '@mathesar/routes/urls';
import { tables as tablesStore } from '@mathesar/stores/tables';
- import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
- } from '@mathesar/AppTypes';
+ import type { Database, SchemaEntry } from '@mathesar/AppTypes';
export let exploration: QueryInstance;
- export let database: SuccessfullyConnectedDatabase;
+ export let database: Database;
export let schema: SchemaEntry;
$: baseTable = $tablesStore.data.get(exploration.base_table);
diff --git a/mathesar_ui/src/pages/schema/ExplorationsList.svelte b/mathesar_ui/src/pages/schema/ExplorationsList.svelte
index 6980414a10..e900014e42 100644
--- a/mathesar_ui/src/pages/schema/ExplorationsList.svelte
+++ b/mathesar_ui/src/pages/schema/ExplorationsList.svelte
@@ -1,15 +1,12 @@
diff --git a/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte b/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte
index 7fb5e31a81..d4224c7d9d 100644
--- a/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte
+++ b/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte
@@ -3,10 +3,7 @@
ControlledModal,
type ModalController,
} from '@mathesar-component-library';
- import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
- } from '@mathesar/AppTypes';
+ import type { Database, SchemaEntry } from '@mathesar/AppTypes';
import Identifier from '@mathesar/components/Identifier.svelte';
import {
setUsersStoreInContext,
@@ -18,7 +15,7 @@
import type { ObjectRoleMap } from '@mathesar/utils/permissions';
export let controller: ModalController;
- export let database: SuccessfullyConnectedDatabase;
+ export let database: Database;
export let schema: SchemaEntry;
const usersStore = setUsersStoreInContext();
diff --git a/mathesar_ui/src/pages/schema/SchemaExplorations.svelte b/mathesar_ui/src/pages/schema/SchemaExplorations.svelte
index 9016768f9a..263e4a7692 100644
--- a/mathesar_ui/src/pages/schema/SchemaExplorations.svelte
+++ b/mathesar_ui/src/pages/schema/SchemaExplorations.svelte
@@ -1,9 +1,6 @@
diff --git a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
index c9da932132..e71ceec904 100644
--- a/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
+++ b/mathesar_ui/src/routes/AuthenticatedRoutes.svelte
@@ -11,7 +11,7 @@
const userProfileStore = getUserProfileStoreFromContext();
$: userProfile = $userProfileStore;
- $: firstDatabase = $databases.successfulConnections?.[0];
+ $: firstDatabase = $databases.data?.[0];
{#if firstDatabase}
diff --git a/mathesar_ui/src/routes/DataExplorerRoute.svelte b/mathesar_ui/src/routes/DataExplorerRoute.svelte
index 75d2d69c60..be960e6bce 100644
--- a/mathesar_ui/src/routes/DataExplorerRoute.svelte
+++ b/mathesar_ui/src/routes/DataExplorerRoute.svelte
@@ -1,9 +1,6 @@
diff --git a/mathesar_ui/src/routes/RecordPageRoute.svelte b/mathesar_ui/src/routes/RecordPageRoute.svelte
index 2c653e5a5b..eecccf3d51 100644
--- a/mathesar_ui/src/routes/RecordPageRoute.svelte
+++ b/mathesar_ui/src/routes/RecordPageRoute.svelte
@@ -2,13 +2,10 @@
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
import RecordPage from '@mathesar/pages/record/RecordPage.svelte';
import type { TableEntry } from '@mathesar/api/types/tables';
- import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
- } from '@mathesar/AppTypes';
+ import type { Database, SchemaEntry } from '@mathesar/AppTypes';
import RecordStore from '@mathesar/pages/record/RecordStore';
- export let database: SuccessfullyConnectedDatabase;
+ export let database: Database;
export let schema: SchemaEntry;
export let table: TableEntry;
export let recordPk: string;
diff --git a/mathesar_ui/src/routes/SchemaRoute.svelte b/mathesar_ui/src/routes/SchemaRoute.svelte
index a863a3be45..164449b2d7 100644
--- a/mathesar_ui/src/routes/SchemaRoute.svelte
+++ b/mathesar_ui/src/routes/SchemaRoute.svelte
@@ -2,7 +2,7 @@
import { onMount } from 'svelte';
import { Route } from 'tinro';
- import type { SuccessfullyConnectedDatabase } from '@mathesar/AppTypes';
+ import type { Database } from '@mathesar/AppTypes';
import ErrorPage from '@mathesar/pages/ErrorPage.svelte';
import SchemaPage from '@mathesar/pages/schema/SchemaPage.svelte';
import { currentSchemaId, schemas } from '@mathesar/stores/schemas';
@@ -16,7 +16,7 @@
const userProfile = getUserProfileStoreFromContext();
- export let database: SuccessfullyConnectedDatabase;
+ export let database: Database;
export let schemaId: number;
$: $currentSchemaId = schemaId;
diff --git a/mathesar_ui/src/routes/TableRoute.svelte b/mathesar_ui/src/routes/TableRoute.svelte
index e13a1de0cd..2d68876158 100644
--- a/mathesar_ui/src/routes/TableRoute.svelte
+++ b/mathesar_ui/src/routes/TableRoute.svelte
@@ -2,17 +2,14 @@
import { onMount } from 'svelte';
import { Route } from 'tinro';
- import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
- } from '@mathesar/AppTypes';
+ import type { Database, SchemaEntry } from '@mathesar/AppTypes';
import ErrorPage from '@mathesar/pages/ErrorPage.svelte';
import TablePage from '@mathesar/pages/table/TablePage.svelte';
import { currentTableId, tables } from '@mathesar/stores/tables';
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
import RecordPageRoute from './RecordPageRoute.svelte';
- export let database: SuccessfullyConnectedDatabase;
+ export let database: Database;
export let schema: SchemaEntry;
export let tableId: number;
diff --git a/mathesar_ui/src/stores/abstract-types/store.ts b/mathesar_ui/src/stores/abstract-types/store.ts
index 84f05fe7bd..ee9a8cf9bc 100644
--- a/mathesar_ui/src/stores/abstract-types/store.ts
+++ b/mathesar_ui/src/stores/abstract-types/store.ts
@@ -4,7 +4,7 @@ import { currentDatabase } from '@mathesar/stores/databases';
import { preloadCommonData } from '@mathesar/utils/preloadData';
import type { Readable, Writable, Unsubscriber } from 'svelte/store';
-import type { SuccessfullyConnectedDatabase } from '@mathesar/AppTypes';
+import type { Database } from '@mathesar/AppTypes';
import type { CancellablePromise } from '@mathesar-component-library';
import type {
AbstractTypesMap,
@@ -17,16 +17,16 @@ import { constructAbstractTypeMapFromResponse } from './abstractTypeCategories';
const commonData = preloadCommonData();
const databasesToAbstractTypesStoreMap: Map<
- SuccessfullyConnectedDatabase['id'],
+ Database['id'],
Writable
> = new Map();
const abstractTypesRequestMap: Map<
- SuccessfullyConnectedDatabase['id'],
+ Database['id'],
CancellablePromise
> = new Map();
export async function refetchTypesForDb(
- databaseId: SuccessfullyConnectedDatabase['id'],
+ databaseId: Database['id'],
): Promise {
const store = databasesToAbstractTypesStoreMap.get(databaseId);
if (!store) {
@@ -75,7 +75,7 @@ export async function refetchTypesForDb(
let preload = true;
function getTypesForDatabase(
- database: SuccessfullyConnectedDatabase,
+ database: Database,
): Writable {
let store = databasesToAbstractTypesStoreMap.get(database.id);
if (!store) {
diff --git a/mathesar_ui/src/stores/databases.ts b/mathesar_ui/src/stores/databases.ts
index abbf40592c..649733d8ca 100644
--- a/mathesar_ui/src/stores/databases.ts
+++ b/mathesar_ui/src/stores/databases.ts
@@ -1,16 +1,10 @@
import { writable, derived } from 'svelte/store';
-import {
- isSuccessfullyConnectedDatabase,
- preloadCommonData,
-} from '@mathesar/utils/preloadData';
+import { preloadCommonData } from '@mathesar/utils/preloadData';
import databaseApi from '@mathesar/api/databases';
import { States } from '@mathesar/api/utils/requestUtils';
import type { Writable } from 'svelte/store';
-import type {
- SuccessfullyConnectedDatabase,
- Database,
-} from '@mathesar/AppTypes';
+import type { Database } from '@mathesar/AppTypes';
import type { PaginatedResponse } from '@mathesar/api/utils/requestUtils';
import type { CancellablePromise } from '@mathesar-component-library';
@@ -25,24 +19,19 @@ export interface DatabaseStoreData {
state: States;
data: Database[];
error?: string;
- successfulConnections: SuccessfullyConnectedDatabase[];
}
export const databases = writable({
preload: true,
state: States.Loading,
data: commonData?.databases ?? [],
- successfulConnections: (commonData?.databases ?? []).filter(
- (database): database is SuccessfullyConnectedDatabase =>
- !('error' in database),
- ),
});
export const currentDatabase = derived(
[currentDBName, databases],
([_currentDBName, databasesStore]) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
- const _databases = databasesStore.successfulConnections;
+ const _databases = databasesStore.data;
if (!_databases?.length) {
return undefined;
}
@@ -65,17 +54,14 @@ export async function reloadDatabases(): Promise<
databaseRequest = databaseApi.list();
const response = await databaseRequest;
const data = response.results || [];
- const successDatabases = data.filter(isSuccessfullyConnectedDatabase);
databases.set({
state: States.Done,
data,
- successfulConnections: successDatabases,
});
return response;
} catch (err) {
databases.set({
data: [],
- successfulConnections: [],
state: States.Error,
error: err instanceof Error ? err.message : undefined,
});
diff --git a/mathesar_ui/src/stores/schemas.ts b/mathesar_ui/src/stores/schemas.ts
index 01639be86c..f860c27cb7 100644
--- a/mathesar_ui/src/stores/schemas.ts
+++ b/mathesar_ui/src/stores/schemas.ts
@@ -11,11 +11,7 @@ import {
} from '@mathesar/api/utils/requestUtils';
import type { PaginatedResponse } from '@mathesar/api/utils/requestUtils';
-import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
- SchemaResponse,
-} from '@mathesar/AppTypes';
+import type { Database, SchemaEntry, SchemaResponse } from '@mathesar/AppTypes';
import type { CancellablePromise } from '@mathesar-component-library';
import { currentDBName } from './databases';
@@ -32,11 +28,11 @@ export interface DBSchemaStoreData {
}
const dbSchemaStoreMap: Map<
- SuccessfullyConnectedDatabase['name'],
+ Database['name'],
Writable
> = new Map();
const dbSchemasRequestMap: Map<
- SuccessfullyConnectedDatabase['name'],
+ Database['name'],
CancellablePromise | undefined>
> = new Map();
@@ -47,7 +43,7 @@ function findStoreBySchemaId(id: SchemaEntry['id']) {
}
function setDBSchemaStore(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schemas: SchemaResponse[],
): Writable {
const schemaMap: DBSchemaStoreData['data'] = new Map();
@@ -71,7 +67,7 @@ function setDBSchemaStore(
}
function updateSchemaInDBSchemaStore(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schema: SchemaResponse,
) {
const store = dbSchemaStoreMap.get(database);
@@ -87,7 +83,7 @@ function updateSchemaInDBSchemaStore(
}
function removeSchemaInDBSchemaStore(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schemaId: SchemaEntry['id'],
) {
const store = dbSchemaStoreMap.get(database);
@@ -103,7 +99,7 @@ function removeSchemaInDBSchemaStore(
}
export function addCountToSchemaNumTables(
- database: SuccessfullyConnectedDatabase,
+ database: Database,
schema: SchemaEntry,
count: number,
) {
@@ -144,7 +140,7 @@ export function addCountToSchemaNumExplorations(
}
export async function refetchSchemasForDB(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
): Promise {
const store = dbSchemaStoreMap.get(database);
if (!store) {
@@ -181,7 +177,7 @@ export async function refetchSchemasForDB(
}
export async function refetchSchema(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schemaId: SchemaEntry['id'],
): Promise {
const store = dbSchemaStoreMap.get(database);
@@ -207,7 +203,7 @@ export async function refetchSchema(
let preload = true;
export function getSchemasStoreForDB(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
): Writable {
let store = dbSchemaStoreMap.get(database);
if (!store) {
@@ -229,7 +225,7 @@ export function getSchemasStoreForDB(
}
export function getSchemaInfo(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schemaId: SchemaEntry['id'],
): SchemaEntry | undefined {
const store = dbSchemaStoreMap.get(database);
@@ -240,7 +236,7 @@ export function getSchemaInfo(
}
export async function createSchema(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schemaName: SchemaEntry['name'],
schemaDescription: SchemaEntry['description'],
): Promise {
@@ -254,7 +250,7 @@ export async function createSchema(
}
export async function updateSchema(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schema: SchemaEntry,
): Promise {
const url = `/api/db/v0/schemas/${schema.id}/`;
@@ -267,7 +263,7 @@ export async function updateSchema(
}
export async function deleteSchema(
- database: SuccessfullyConnectedDatabase['name'],
+ database: Database['name'],
schemaId: SchemaEntry['id'],
): Promise {
await deleteAPI(`/api/db/v0/schemas/${schemaId}/`);
diff --git a/mathesar_ui/src/stores/tables.ts b/mathesar_ui/src/stores/tables.ts
index 6f39bc45c5..a8a21d8bf9 100644
--- a/mathesar_ui/src/stores/tables.ts
+++ b/mathesar_ui/src/stores/tables.ts
@@ -28,11 +28,7 @@ import type {
SplitTableRequest,
SplitTableResponse,
} from '@mathesar/api/types/tables/split_table';
-import type {
- DBObjectEntry,
- SuccessfullyConnectedDatabase,
- SchemaEntry,
-} from '@mathesar/AppTypes';
+import type { DBObjectEntry, Database, SchemaEntry } from '@mathesar/AppTypes';
import { invalidIf } from '@mathesar/components/form';
import type { PaginatedResponse } from '@mathesar/api/utils/requestUtils';
import {
@@ -193,7 +189,7 @@ function findAndUpdateTableStore(id: TableEntry['id'], tableEntry: TableEntry) {
}
export function deleteTable(
- database: SuccessfullyConnectedDatabase,
+ database: Database,
schema: SchemaEntry,
tableId: TableEntry['id'],
): CancellablePromise {
@@ -240,7 +236,7 @@ export function updateTableMetaData(
}
export function createTable(
- database: SuccessfullyConnectedDatabase,
+ database: Database,
schema: SchemaEntry,
tableArgs: {
name?: string;
diff --git a/mathesar_ui/src/stores/users.ts b/mathesar_ui/src/stores/users.ts
index 8af77df9e0..73eca377c5 100644
--- a/mathesar_ui/src/stores/users.ts
+++ b/mathesar_ui/src/stores/users.ts
@@ -12,10 +12,7 @@ import userApi, {
import type { RequestStatus } from '@mathesar/api/utils/requestUtils';
import { getErrorMessage } from '@mathesar/utils/errors';
import type { MakeWritablePropertiesReadable } from '@mathesar/utils/typeUtils';
-import type {
- SuccessfullyConnectedDatabase,
- SchemaEntry,
-} from '@mathesar/AppTypes';
+import type { Database, SchemaEntry } from '@mathesar/AppTypes';
import {
rolesAllowOperation,
type AccessOperation,
@@ -52,7 +49,7 @@ export class UserModel {
hasPermission(
dbObject: {
- database?: Pick;
+ database?: Pick;
schema?: Pick;
},
operation: AccessOperation,
@@ -82,7 +79,7 @@ export class UserModel {
return rolesAllowOperation(operation, roles);
}
- getRoleForDb(database: Pick) {
+ getRoleForDb(database: Pick) {
return this.databaseRoles.get(database.id);
}
@@ -90,11 +87,11 @@ export class UserModel {
return this.schemaRoles.get(schema.id);
}
- hasDirectDbAccess(database: Pick) {
+ hasDirectDbAccess(database: Pick) {
return this.databaseRoles.has(database.id);
}
- hasDbAccess(database: Pick) {
+ hasDbAccess(database: Pick) {
return this.hasDirectDbAccess(database) || this.isSuperUser;
}
@@ -103,7 +100,7 @@ export class UserModel {
}
hasSchemaAccess(
- database: Pick,
+ database: Pick,
schema: Pick,
) {
return this.hasDbAccess(database) || this.hasDirectSchemaAccess(schema);
@@ -258,7 +255,7 @@ class WritableUsersStore {
async addDatabaseRoleForUser(
userId: number,
- database: Pick,
+ database: Pick,
role: UserRole,
) {
const dbRole = await userApi.addDatabaseRole(userId, database.id, role);
@@ -275,7 +272,7 @@ class WritableUsersStore {
async removeDatabaseAccessForUser(
userId: number,
- database: Pick,
+ database: Pick,
) {
const user = get(this.users).find((entry) => entry.id === userId);
const dbRole = user?.getRoleForDb(database);
@@ -330,15 +327,13 @@ class WritableUsersStore {
}
}
- getUsersWithAccessToDb(database: Pick) {
+ getUsersWithAccessToDb(database: Pick) {
return derived(this.users, ($users) =>
$users.filter((user) => user.hasDbAccess(database)),
);
}
- getUsersWithoutAccessToDb(
- database: Pick,
- ) {
+ getUsersWithoutAccessToDb(database: Pick) {
return derived(this.users, ($users) =>
$users.filter((user) => !user.hasDbAccess(database)),
);
@@ -361,7 +356,7 @@ class WritableUsersStore {
}
getUsersWithAccessToSchema(
- database: Pick,
+ database: Pick,
schema: Pick,
) {
return derived(this.users, ($users) =>
diff --git a/mathesar_ui/src/utils/preloadData.ts b/mathesar_ui/src/utils/preloadData.ts
index 8ee0a2b8ef..77dce99970 100644
--- a/mathesar_ui/src/utils/preloadData.ts
+++ b/mathesar_ui/src/utils/preloadData.ts
@@ -1,8 +1,8 @@
import type {
- SuccessfullyConnectedDatabase,
SchemaResponse,
AbstractTypeResponse,
Database,
+ SuccessfullyConnectedDatabase,
} from '@mathesar/AppTypes';
import type { TableEntry } from '@mathesar/api/types/tables';
import type { QueryInstance } from '@mathesar/api/types/queries';
From a94015deaaf9ca30ec8b09c5f1caad394bd5da0c Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 5 Oct 2023 16:41:54 +0530
Subject: [PATCH 035/111] fixed formatting
---
mathesar_ui/src/pages/admin-users/AdminNavigation.svelte | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
index 55e485f215..40218f101d 100644
--- a/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
+++ b/mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
@@ -47,9 +47,9 @@
class="menu-item menu-item-link"
use:active
>
- Database Connection
+
+ Database Connection
+
From 5eb453f385edc87db06afb780b6ce71fcb453f02 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 5 Oct 2023 22:55:55 +0530
Subject: [PATCH 036/111] loader while reloading the db
---
.../AddDatabaseConnection.svelte | 17 ++++++++-----
.../DatabaseConnectionForm.svelte | 21 ++++++++--------
.../EditDatabaseConnection.svelte | 24 +++++++++++++++----
3 files changed, 41 insertions(+), 21 deletions(-)
diff --git a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
index a60bf7ea97..0b59eea703 100644
--- a/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/AddDatabaseConnection.svelte
@@ -13,12 +13,17 @@
import FormBox from '../admin-users/FormBox.svelte';
import DatabaseConnectionForm from './DatabaseConnectionForm.svelte';
- async function handleSuccess(event: CustomEvent) {
- const database = event.detail;
+ async function handleSuccess(database: Database) {
toast.success(`${database.name} connected successfully!`);
- await reflectApi.reflect();
- await reloadDatabases();
- router.goto(getDatabasePageUrl(database.name));
+
+ try {
+ await reflectApi.reflect();
+ await reloadDatabases();
+ } catch (e) {
+ toast.fromError(e);
+ } finally {
+ router.goto(getDatabasePageUrl(database.name));
+ }
}
@@ -34,5 +39,5 @@
Add Database Connection
-
+
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
index 98ffefdb41..05cf4d230a 100644
--- a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
@@ -13,14 +13,13 @@
import { createEventDispatcher } from 'svelte';
import { extractDetailedFieldBasedErrors } from '@mathesar/api/utils/errors';
import WarningBox from '@mathesar/components/message-boxes/WarningBox.svelte';
-
- const dispatch = createEventDispatcher<{
- create: Database;
- update: undefined;
- }>();
+ import DocsLink from '@mathesar/components/DocsLink.svelte';
let databaseNameProp: string | undefined = undefined;
export { databaseNameProp as databaseName };
+ export let onCreate: ((database: Database) => Promise) | undefined =
+ undefined;
+ export let onUpdate: (() => Promise) | undefined = undefined;
$: database = $databases.data?.find((db) => db.name === databaseNameProp);
$: isNewConnection = !database;
@@ -29,7 +28,7 @@
$: databaseName = requiredField(database?.db_name ?? '');
$: username = requiredField(database?.username ?? '');
$: host = requiredField(database?.host ?? '');
- $: port = requiredField(database?.port ?? '', [
+ $: port = requiredField(database?.port ?? '5432', [
(value) =>
!Number.isNaN(+value)
? { type: 'valid' }
@@ -83,11 +82,11 @@
async function saveConnectionDetails() {
if (isNewConnection) {
const newDatabase = await addNewDatabaseConnection();
- dispatch('create', newDatabase);
+ await onCreate?.(newDatabase);
} else {
await updateDatabaseConnection();
form.reset();
- dispatch('update');
+ await onUpdate?.();
}
}
@@ -167,9 +166,9 @@
{#if isNewConnection}
- Every PostgreSQL database includes the "public" schema. This protected
- schema can be read by anybody who accesses the database. They will all be
- namespaced into Mathesar-specific schemas for safety and organization.
+ For Mathesar to function properly, we will add a number of functions and
+ types to this database. They will all be namespaced into
+ Mathesar-specific schemas for safety and organization.
{/if}
@@ -34,5 +46,9 @@
Edit Database Connection
-
+
From ddb942b2fddb2fb9573ab4fcc3b81c8bffaf4b2a Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Thu, 5 Oct 2023 23:09:28 +0530
Subject: [PATCH 037/111] placeholder for links
---
mathesar_ui/src/components/form/GridFormInput.svelte | 9 +++++++--
.../DatabaseConnectionForm.svelte | 8 ++++++--
.../DeleteDatabaseConnectionConfirmationModal.svelte | 12 ++++++++++--
3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/mathesar_ui/src/components/form/GridFormInput.svelte b/mathesar_ui/src/components/form/GridFormInput.svelte
index a32c604bcf..a6e6442be7 100644
--- a/mathesar_ui/src/components/form/GridFormInput.svelte
+++ b/mathesar_ui/src/components/form/GridFormInput.svelte
@@ -33,9 +33,14 @@
- {#if help}
+ {#if $$slots.help || help}
- {help}
+ {#if $$slots.help}
+
+ {/if}
+ {#if help}
+ {help}
+ {/if}
{/if}
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
index 05cf4d230a..1fc7828c40 100644
--- a/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionForm.svelte
@@ -150,8 +150,12 @@
label="Username *"
field={username}
input={{ component: TextInput }}
- help="The user will need to have SUPERUSER or DB OWNER privileges on the database. Why is this needed?."
- />
+ >
+
+ The user will need to have SUPERUSER or DB OWNER privileges on the
+ database. Why is this needed?.
+
+
();
@@ -54,10 +55,17 @@
Mathesar's custom data types.
- Learn more about the implications of deleting the Mathesar schema.
+
+
+ Learn more about the implications of deleting the
+ Mathesar schema.
+
-
From fe6c7b622b9f6dd4722a5427b96bdca95c42ceff Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Fri, 6 Oct 2023 01:29:01 +0530
Subject: [PATCH 046/111] no condition on schema page on connection error
---
mathesar_ui/src/routes/DatabaseRoute.svelte | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/mathesar_ui/src/routes/DatabaseRoute.svelte b/mathesar_ui/src/routes/DatabaseRoute.svelte
index 773f9fefec..4ba7e544e5 100644
--- a/mathesar_ui/src/routes/DatabaseRoute.svelte
+++ b/mathesar_ui/src/routes/DatabaseRoute.svelte
@@ -7,7 +7,6 @@
import ErrorPage from '@mathesar/pages/ErrorPage.svelte';
import { currentDBName, databases } from '@mathesar/stores/databases';
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
- import { isSuccessfullyConnectedDatabase } from '@mathesar/utils/database';
import SchemaRoute from './SchemaRoute.svelte';
export let databaseName: string;
@@ -29,11 +28,9 @@
- {#if isSuccessfullyConnectedDatabase(database)}
-
-
-
- {/if}
+
+
+
{:else}
Database with name {databaseName} is not found.
From e59072581ebc59b1c3578aa1779e784e95fb69ff Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Fri, 6 Oct 2023 01:37:26 +0530
Subject: [PATCH 047/111] disconnect database flow ux fixes
---
.../DatabaseConnectionsList.svelte | 4 ---
.../EditDatabaseConnection.svelte | 35 +++++++++++++++++--
.../src/pages/database/ConnectionError.svelte | 9 ++---
.../src/pages/database/DatabaseDetails.svelte | 4 +--
4 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte b/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
index 468979efca..ea4e810d49 100644
--- a/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
+++ b/mathesar_ui/src/pages/database-connection/DatabaseConnectionsList.svelte
@@ -12,7 +12,6 @@
import EntityContainerWithFilterBar from '@mathesar/components/EntityContainerWithFilterBar.svelte';
import { AnchorButton, Icon } from '@mathesar/component-library';
import { labeledCount } from '@mathesar/utils/languageUtils';
- import { isSuccessfullyConnectedDatabase } from '@mathesar/utils/database';
import DatabaseConnectionSkeleton from './DatabaseConnectionSkeleton.svelte';
import { makeSimplePageTitle } from '../pageTitleUtils';
import DatabaseConnectionItem from './DatabaseConnectionItem.svelte';
@@ -24,9 +23,6 @@
$: databasesLoadError = $databases.error;
function isMatch(database: Database, q: string) {
- if (!isSuccessfullyConnectedDatabase(database)) {
- return database.name.toLowerCase().includes(q);
- }
return (
database.name.toLowerCase().includes(q) ||
database.db_name.toLowerCase().includes(q)
diff --git a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
index d6f90bb731..7421bb87c5 100644
--- a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
@@ -1,19 +1,27 @@
+
+{#if database}
+
+
+
+
+{/if}
diff --git a/mathesar_ui/src/pages/database/ConnectionError.svelte b/mathesar_ui/src/pages/database/ConnectionError.svelte
index ff4a59372b..9f3c307a30 100644
--- a/mathesar_ui/src/pages/database/ConnectionError.svelte
+++ b/mathesar_ui/src/pages/database/ConnectionError.svelte
@@ -1,4 +1,5 @@
- Error connecting to the database
+ {database.error}
{#if !isSuccessfullyConnectedDatabase(database)}
-
+
{:else}
Date: Fri, 6 Oct 2023 01:44:45 +0530
Subject: [PATCH 048/111] lint fixes
---
.../pages/database-connection/EditDatabaseConnection.svelte | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
index 7421bb87c5..66a2e53894 100644
--- a/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
+++ b/mathesar_ui/src/pages/database-connection/EditDatabaseConnection.svelte
@@ -9,12 +9,12 @@
import { databases, reloadDatabases } from '@mathesar/stores/databases';
import { reflectApi } from '@mathesar/api/reflect';
import { router } from 'tinro';
- import FormBox from '../admin-users/FormBox.svelte';
- import DatabaseConnectionForm from './DatabaseConnectionForm.svelte';
- import DeleteDatabaseConnectionConfirmationModal from '../database/DeleteDatabaseConnectionConfirmationModal.svelte';
import { modal } from '@mathesar/stores/modal';
import Button from '@mathesar/component-library/button/Button.svelte';
import { Icon } from '@mathesar/component-library';
+ import FormBox from '../admin-users/FormBox.svelte';
+ import DatabaseConnectionForm from './DatabaseConnectionForm.svelte';
+ import DeleteDatabaseConnectionConfirmationModal from '../database/DeleteDatabaseConnectionConfirmationModal.svelte';
export let databaseName: string;
From b11f2b04a8f161183181b852c20805dfd04f3c46 Mon Sep 17 00:00:00 2001
From: Rajat Vijay
Date: Mon, 9 Oct 2023 16:58:39 +0530
Subject: [PATCH 049/111] move window.Mathesar.translations init in
translations file
---
config/context_processors.py | 4 ++++
mathesar/templates/mathesar/index.html | 19 ++++++++++---------
mathesar/utils/frontend.py | 1 +
mathesar_ui/src/global.d.ts | 4 ++--
mathesar_ui/src/i18n/en/index.ts | 5 ++++-
mathesar_ui/src/i18n/i18n-util.ts | 14 ++++++++++++++
mathesar_ui/src/i18n/ja/index.ts | 7 ++++++-
7 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/config/context_processors.py b/config/context_processors.py
index 1c8e00ceae..4906bbf3e4 100644
--- a/config/context_processors.py
+++ b/config/context_processors.py
@@ -38,13 +38,17 @@ def get_i18n_settings(manifest_data, development_mode):
if development_mode is True:
module_translations_file_path = f'{client_dev_url}/src/i18n/{preferred_language}/index.ts'
+ legacy_translations_file_path = f'{client_dev_url}/src/i18n/{preferred_language}/index.ts'
else:
try:
module_translations_file_path = static(manifest_data[preferred_language]["file"])
+ legacy_translations_file_path = static(manifest_data[f"{preferred_language}-legacy"]["file"])
except KeyError:
module_translations_file_path = static(manifest_data[default_language]["file"])
+ legacy_translations_file_path = static(manifest_data[f"{default_language}-legacy"]["file"])
return {
'module_translations_file_path': module_translations_file_path,
+ 'legacy_translations_file_path': legacy_translations_file_path,
'preferred_language': preferred_language
}
diff --git a/mathesar/templates/mathesar/index.html b/mathesar/templates/mathesar/index.html
index 0b979b348f..30e8593603 100644
--- a/mathesar/templates/mathesar/index.html
+++ b/mathesar/templates/mathesar/index.html
@@ -19,15 +19,7 @@
{% endfor %}
{% endif %}
-
+
{% if development_mode %}
@@ -62,6 +54,15 @@
nomodule
src="{% static manifest_data.legacy_polyfill_js %}"
>
+
From 277592dde80e30a6c25905a60f406202aef3f520 Mon Sep 17 00:00:00 2001
From: Anish
Date: Tue, 10 Oct 2023 20:25:59 +0530
Subject: [PATCH 054/111] use value of the fkey cell instead of the record id
---
mathesar_ui/src/components/cell-fabric/CellFabric.svelte | 1 +
.../components/linked-record/LinkedRecordCell.svelte | 5 ++++-
.../cell-fabric/data-types/components/typeDefinitions.ts | 4 +++-
.../src/systems/record-selector/RecordSelectorContent.svelte | 2 +-
.../src/systems/record-selector/RecordSelectorController.ts | 2 ++
.../src/systems/record-selector/RecordSelectorTable.svelte | 2 +-
6 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/mathesar_ui/src/components/cell-fabric/CellFabric.svelte b/mathesar_ui/src/components/cell-fabric/CellFabric.svelte
index 8a405123da..d77a167437 100644
--- a/mathesar_ui/src/components/cell-fabric/CellFabric.svelte
+++ b/mathesar_ui/src/components/cell-fabric/CellFabric.svelte
@@ -55,6 +55,7 @@
,
LinkedRecordCellExternalProps {
+ columnFabric?: ProcessedColumn;
recordSummary?: string;
setRecordSummary?: (recordId: string, recordSummary: string) => void;
}
diff --git a/mathesar_ui/src/systems/record-selector/RecordSelectorContent.svelte b/mathesar_ui/src/systems/record-selector/RecordSelectorContent.svelte
index ed17a9aba8..ecdf011fa7 100644
--- a/mathesar_ui/src/systems/record-selector/RecordSelectorContent.svelte
+++ b/mathesar_ui/src/systems/record-selector/RecordSelectorContent.svelte
@@ -96,7 +96,7 @@
template,
transitiveData: buildRecordSummariesForSheet(previewData),
});
- submitResult({ recordId, recordSummary });
+ submitResult({ recordId, recordSummary, record });
} catch (err) {
toast.error(getErrorMessage(err));
// TODO set errors in tabularData to appear within cells
diff --git a/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts b/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts
index 81768f91c1..5ae080d971 100644
--- a/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts
+++ b/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts
@@ -4,6 +4,7 @@ import { writable } from 'svelte/store';
import type { Column } from '@mathesar/api/types/tables/columns';
import type { DBObjectEntry } from '@mathesar/AppTypes';
import type { RecordSelectorPurpose } from './recordSelectorUtils';
+import type { Result as ApiRecord } from '@mathesar/api/types/tables/records';
interface RecordSelectorControllerProps {
onOpen?: () => void;
@@ -16,6 +17,7 @@ type FkCellValue = string | number;
export interface RecordSelectorResult {
recordId: FkCellValue;
recordSummary: string;
+ record: ApiRecord;
}
export class RecordSelectorController {
diff --git a/mathesar_ui/src/systems/record-selector/RecordSelectorTable.svelte b/mathesar_ui/src/systems/record-selector/RecordSelectorTable.svelte
index b9bc990dbd..567a354d0f 100644
--- a/mathesar_ui/src/systems/record-selector/RecordSelectorTable.svelte
+++ b/mathesar_ui/src/systems/record-selector/RecordSelectorTable.svelte
@@ -143,7 +143,7 @@
inputData: buildInputData(record),
transitiveData: $recordSummaries,
});
- submitResult({ recordId, recordSummary });
+ submitResult({ recordId, recordSummary, record });
}
function submitSelection() {
From 3ec0709240707b6757576d51598d8d4c129ad95b Mon Sep 17 00:00:00 2001
From: Anish
Date: Wed, 11 Oct 2023 00:06:53 +0530
Subject: [PATCH 055/111] make linter happy
---
.../components/linked-record/LinkedRecordCell.svelte | 5 ++---
.../cell-fabric/data-types/components/typeDefinitions.ts | 2 +-
.../src/systems/record-selector/RecordSelectorController.ts | 2 +-
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
index dd2ee3defa..09eff7789a 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
@@ -42,10 +42,9 @@
}
event?.stopPropagation();
const result = await recordSelector.acquireUserInput({ tableId });
- const linkFk = columnFabric!.linkFk;
- const LinkedFkid = linkFk!.referent_columns[0];
+ const LinkedFkid = columnFabric.linkFk?.referent_columns[0];
if (result) {
- value = result.record[LinkedFkid];
+ value = result.record[LinkedFkid!];
setRecordSummary(String(result.recordId), result.recordSummary);
dispatch('update', { value });
}
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts b/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts
index 2020965a29..b510849dcd 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts
@@ -46,7 +46,7 @@ export interface LinkedRecordCellExternalProps {
export interface LinkedRecordCellProps
extends CellTypeProps,
LinkedRecordCellExternalProps {
- columnFabric?: ProcessedColumn;
+ columnFabric: ProcessedColumn;
recordSummary?: string;
setRecordSummary?: (recordId: string, recordSummary: string) => void;
}
diff --git a/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts b/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts
index 5ae080d971..22f503f8c2 100644
--- a/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts
+++ b/mathesar_ui/src/systems/record-selector/RecordSelectorController.ts
@@ -3,8 +3,8 @@ import { writable } from 'svelte/store';
import type { Column } from '@mathesar/api/types/tables/columns';
import type { DBObjectEntry } from '@mathesar/AppTypes';
-import type { RecordSelectorPurpose } from './recordSelectorUtils';
import type { Result as ApiRecord } from '@mathesar/api/types/tables/records';
+import type { RecordSelectorPurpose } from './recordSelectorUtils';
interface RecordSelectorControllerProps {
onOpen?: () => void;
From d3a13629c9c4bb29ba3b5467d6cadfa1c61a7d01 Mon Sep 17 00:00:00 2001
From: Anish
Date: Wed, 11 Oct 2023 00:22:13 +0530
Subject: [PATCH 056/111] handle warnings
---
.../components/linked-record/LinkedRecordCell.svelte | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
index 09eff7789a..5f06c67b1f 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
@@ -44,7 +44,12 @@
const result = await recordSelector.acquireUserInput({ tableId });
const LinkedFkid = columnFabric.linkFk?.referent_columns[0];
if (result) {
- value = result.record[LinkedFkid!];
+ if (LinkedFkid !== undefined && LinkedFkid !== null){
+ value = result.record[LinkedFkid];
+ }
+ else {
+ value = result.recordId;
+ }
setRecordSummary(String(result.recordId), result.recordSummary);
dispatch('update', { value });
}
From 6990b5ad4ec31a377562ae37b37d8a8e9a67864a Mon Sep 17 00:00:00 2001
From: Anish
Date: Wed, 11 Oct 2023 00:47:35 +0530
Subject: [PATCH 057/111] add a whitespace
---
.../data-types/components/linked-record/LinkedRecordCell.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
index 5f06c67b1f..6c0666f586 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
@@ -44,7 +44,7 @@
const result = await recordSelector.acquireUserInput({ tableId });
const LinkedFkid = columnFabric.linkFk?.referent_columns[0];
if (result) {
- if (LinkedFkid !== undefined && LinkedFkid !== null){
+ if (LinkedFkid !== undefined && LinkedFkid !== null) {
value = result.record[LinkedFkid];
}
else {
From 5a1ec7f7e1ef6a0822ba5f4e579a650b9e4c8c1e Mon Sep 17 00:00:00 2001
From: Anish
Date: Wed, 11 Oct 2023 00:53:06 +0530
Subject: [PATCH 058/111] ran prettier
---
.../components/linked-record/LinkedRecordCell.svelte | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
index 6c0666f586..dc2a231e9f 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
@@ -46,8 +46,7 @@
if (result) {
if (LinkedFkid !== undefined && LinkedFkid !== null) {
value = result.record[LinkedFkid];
- }
- else {
+ } else {
value = result.recordId;
}
setRecordSummary(String(result.recordId), result.recordSummary);
From 387f51e6de1222eabd1c578e90dfc5422b7aafc1 Mon Sep 17 00:00:00 2001
From: Anish
Date: Thu, 12 Oct 2023 23:40:15 +0530
Subject: [PATCH 059/111] add check & exclude cons in the cons mapping dict
---
mathesar/api/serializers/constraints.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/mathesar/api/serializers/constraints.py b/mathesar/api/serializers/constraints.py
index 761f211099..825ba47cff 100644
--- a/mathesar/api/serializers/constraints.py
+++ b/mathesar/api/serializers/constraints.py
@@ -139,6 +139,10 @@ class Meta:
'foreignkey': ForeignKeyConstraintSerializer,
'primary': BaseConstraintSerializer,
'unique': BaseConstraintSerializer,
+ # Even though 'check' & 'exclude' constraints are currently unsupported it's added here
+ # so that the app doesn't break in case these constraints are already present.
+ 'check': BaseConstraintSerializer,
+ 'exclude': BaseConstraintSerializer
}
def get_mapping_field(self, data):
From 9c0253811cf0d64583aebca8d016d4ac2eda0f29 Mon Sep 17 00:00:00 2001
From: Anish Umale
Date: Mon, 16 Oct 2023 18:44:04 +0530
Subject: [PATCH 060/111] rename LinkedFkid to LinkedFkCellValue
---
.../components/linked-record/LinkedRecordCell.svelte | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
index dc2a231e9f..78948cf0ea 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
@@ -42,10 +42,10 @@
}
event?.stopPropagation();
const result = await recordSelector.acquireUserInput({ tableId });
- const LinkedFkid = columnFabric.linkFk?.referent_columns[0];
+ const LinkedFkCellValue = columnFabric.linkFk?.referent_columns[0];
if (result) {
- if (LinkedFkid !== undefined && LinkedFkid !== null) {
- value = result.record[LinkedFkid];
+ if (LinkedFkCellValue !== undefined && LinkedFkCellValue !== null) {
+ value = result.record[LinkedFkCellValue];
} else {
value = result.recordId;
}
From bc145a14e6bfcf892a73af7fd1f1c386c876551c Mon Sep 17 00:00:00 2001
From: Anish
Date: Tue, 17 Oct 2023 13:35:27 +0530
Subject: [PATCH 061/111] fix validator to allow creating only 'f' 'p' & 'u'
constraints
---
mathesar/api/serializers/constraints.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mathesar/api/serializers/constraints.py b/mathesar/api/serializers/constraints.py
index 825ba47cff..5a5955e04e 100644
--- a/mathesar/api/serializers/constraints.py
+++ b/mathesar/api/serializers/constraints.py
@@ -154,10 +154,12 @@ def get_mapping_field(self, data):
return constraint_type
def create(self, validated_data):
+ print('yo')
serializer = self.get_serializer_class(self.get_mapping_field(validated_data))
return serializer.create(validated_data)
def run_validation(self, data):
+ print('rv')
if referent_table := data.get('referent_table', None):
referent_table_name = Table.current_objects.get(id=referent_table).name
if any(
@@ -169,7 +171,7 @@ def run_validation(self, data):
field='referent_table'
)
constraint_type = data.get('type', None)
- if constraint_type not in self.serializers_mapping.keys():
+ if constraint_type not in ('foreignkey', 'primary', 'unique'):
raise UnsupportedConstraintAPIException(constraint_type=constraint_type)
columns = data.get('columns', None)
if columns == []:
From 727ddfbeac51fd0e66bb0ee927be375c986a6d55 Mon Sep 17 00:00:00 2001
From: Anish
Date: Tue, 17 Oct 2023 13:36:24 +0530
Subject: [PATCH 062/111] rm print statements
---
mathesar/api/serializers/constraints.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/mathesar/api/serializers/constraints.py b/mathesar/api/serializers/constraints.py
index 5a5955e04e..0dc9b8cde8 100644
--- a/mathesar/api/serializers/constraints.py
+++ b/mathesar/api/serializers/constraints.py
@@ -154,12 +154,10 @@ def get_mapping_field(self, data):
return constraint_type
def create(self, validated_data):
- print('yo')
serializer = self.get_serializer_class(self.get_mapping_field(validated_data))
return serializer.create(validated_data)
def run_validation(self, data):
- print('rv')
if referent_table := data.get('referent_table', None):
referent_table_name = Table.current_objects.get(id=referent_table).name
if any(
From de023eabc422db98d5839656048d5a1afe4ac010 Mon Sep 17 00:00:00 2001
From: Anish
Date: Thu, 19 Oct 2023 19:18:00 +0530
Subject: [PATCH 063/111] see if tests pass
---
mathesar/tests/conftest.py | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/mathesar/tests/conftest.py b/mathesar/tests/conftest.py
index f3c8f867c9..4b3dae0f01 100644
--- a/mathesar/tests/conftest.py
+++ b/mathesar/tests/conftest.py
@@ -99,13 +99,14 @@ def create_dj_db(request):
def _create_and_add(db_name):
create_db(db_name)
add_db_to_dj_settings(db_name)
+ credentials = settings.DATABASES.get(db_name)
database_model = Database.current_objects.create(
name=db_name,
db_name=db_name,
- username='mathesar',
- password='mathesar',
- host='mathesar_dev_db',
- port=5432
+ username=credentials['USER'],
+ password=credentials['PASSWORD'],
+ host=credentials['HOST'],
+ port=credentials['PORT']
)
return database_model
yield _create_and_add
@@ -128,13 +129,14 @@ def test_db_model(request, test_db_name, django_db_blocker):
add_db_to_dj_settings(test_db_name)
with django_db_blocker.unblock():
+ credentials = settings.DATABASES.get(test_db_name)
database_model = Database.current_objects.create(
name=test_db_name,
db_name=test_db_name,
- username='mathesar',
- password='mathesar',
- host='mathesar_dev_db',
- port=5432
+ username=credentials['USER'],
+ password=credentials['PASSWORD'],
+ host=credentials['HOST'],
+ port=credentials['PORT']
)
yield database_model
database_model.delete()
From f3fc9872fbddc1784b4c91feb338987b50017859 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 01:12:35 +0800
Subject: [PATCH 064/111] add jobs for testing strategy branches
---
.github/workflows/handle-required-checks.yml | 22 ++++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
index 40677fd4bc..13d7f42068 100644
--- a/.github/workflows/handle-required-checks.yml
+++ b/.github/workflows/handle-required-checks.yml
@@ -2,15 +2,7 @@
## This handles the cases where they don't run because no Python or JS file has been changed.
## See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
name: handle-required-checks
-on:
- push:
- paths-ignore:
- - 'mathesar_ui/**'
- - '**.py'
- pull_request:
- paths-ignore:
- - 'mathesar_ui/**'
- - '**.py'
+on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
@@ -20,3 +12,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: 'echo "No tests required"'
+ tests (13):
+ runs-on: ubuntu-latest
+ steps:
+ - run: 'echo "No tests required"'
+ tests (14):
+ runs-on: ubuntu-latest
+ steps:
+ - run: 'echo "No tests required"'
+ tests (15):
+ runs-on: ubuntu-latest
+ steps:
+ - run: 'echo "No tests required"'
From 7cfa9343159ac00cb3d2d4929754f00647ad186d Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 16:42:54 +0800
Subject: [PATCH 065/111] revert matrix job name specification
---
.github/workflows/handle-required-checks.yml | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
index 13d7f42068..277e6d596b 100644
--- a/.github/workflows/handle-required-checks.yml
+++ b/.github/workflows/handle-required-checks.yml
@@ -2,7 +2,7 @@
## This handles the cases where they don't run because no Python or JS file has been changed.
## See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
name: handle-required-checks
-on: [push, pull_request]
+on: [push, pull_request, merge_group]
jobs:
lint:
runs-on: ubuntu-latest
@@ -12,15 +12,3 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: 'echo "No tests required"'
- tests (13):
- runs-on: ubuntu-latest
- steps:
- - run: 'echo "No tests required"'
- tests (14):
- runs-on: ubuntu-latest
- steps:
- - run: 'echo "No tests required"'
- tests (15):
- runs-on: ubuntu-latest
- steps:
- - run: 'echo "No tests required"'
From e5b10b90118beec5addb3cf3f485eeaaf2c2ab5b Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 16:48:31 +0800
Subject: [PATCH 066/111] change push out for merge_group trigger for pytest
---
.github/workflows/run-pytest.yml | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index d20f5a1d31..bf1fbb567e 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -1,23 +1,24 @@
+# Since we're using both the "require pull request" and "require merge queue"
+# requirements for develop and master branches, there's no reason to run tests
+# on every push. Instead, we're using the recommended "merge_group" formulation
+# that runs status checks and reports them whenever a PR is added to the merge
+# queue.
+
name: Run Python tests
on:
- push:
+ pull_request:
paths:
- '*.py'
- 'mathesar/**'
- 'db/**'
- pull_request:
+ merge_group:
paths:
- '*.py'
- 'mathesar/**'
- 'db/**'
-
-
jobs:
tests:
runs-on: ubuntu-latest
- # We only want to run on external PRs, since internal PRs are covered by "push"
- # This prevents this from running twice on internal PRs
- if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
strategy:
matrix:
pg-version: [13, 14, 15]
From 2ec27c89a23eab7f5ac5de263d6619b092db7df0 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:01:34 +0800
Subject: [PATCH 067/111] remove push trigger from fallback
---
.github/workflows/handle-required-checks.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
index 277e6d596b..1a3ee9f937 100644
--- a/.github/workflows/handle-required-checks.yml
+++ b/.github/workflows/handle-required-checks.yml
@@ -2,7 +2,7 @@
## This handles the cases where they don't run because no Python or JS file has been changed.
## See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
name: handle-required-checks
-on: [push, pull_request, merge_group]
+on: [pull_request, merge_group]
jobs:
lint:
runs-on: ubuntu-latest
From 2a8d1b70e99a5d3237247830699898304765cc09 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:02:14 +0800
Subject: [PATCH 068/111] remove path spec from pytest workflow (temp)
---
.github/workflows/run-pytest.yml | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index bf1fbb567e..2e20862920 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -5,17 +5,7 @@
# queue.
name: Run Python tests
-on:
- pull_request:
- paths:
- - '*.py'
- - 'mathesar/**'
- - 'db/**'
- merge_group:
- paths:
- - '*.py'
- - 'mathesar/**'
- - 'db/**'
+on: [pull_request, merge_group]
jobs:
tests:
runs-on: ubuntu-latest
From 3cfd696632dee684e1d8f06be562fd33c4f58aa7 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:13:26 +0800
Subject: [PATCH 069/111] Use branching that will skip with a success output
---
.github/workflows/run-pytest.yml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 2e20862920..4dbae133e0 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -7,8 +7,11 @@
name: Run Python tests
on: [pull_request, merge_group]
jobs:
- tests:
+ python_tests:
runs-on: ubuntu-latest
+ # Using this construct means we'll skip to "success". This avoids the
+ # unrecommended path filtering in this required job.
+ if: ${{ -n hashFiles('*.py', 'mathesar/**', 'db/**') }}
strategy:
matrix:
pg-version: [13, 14, 15]
From 1892f7736d4eb348f2b8aed5b5d01cd6802fa6e3 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:15:37 +0800
Subject: [PATCH 070/111] add run prompting dependent job
---
.github/workflows/run-pytest.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 4dbae133e0..ec40982b9a 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -35,3 +35,5 @@ jobs:
# Override setup.cfg docker-compose db service credentials with in built docker postgres server
- name: Run tests with pytest
run: docker exec -e DJANGO_DATABASE_URL="postgres://postgres:mathesar@localhost:5432/mathesar_django" -e MATHESAR_DATABASES="(mathesar_db_test|postgres://postgres:mathesar@localhost:5432/mathesar_db_test)" mathesar_service_test ./run_pytest.sh
+ tests:
+ needs: python_tests
From 9f47674d3096a0c78cac154fa5cf42d94e15fad1 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:18:08 +0800
Subject: [PATCH 071/111] turn off 'tests' fallback in CI
---
.github/workflows/handle-required-checks.yml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
index 1a3ee9f937..13b60efadc 100644
--- a/.github/workflows/handle-required-checks.yml
+++ b/.github/workflows/handle-required-checks.yml
@@ -8,7 +8,3 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: 'echo "No lint required"'
- tests:
- runs-on: ubuntu-latest
- steps:
- - run: 'echo "No tests required"'
From 9c2d078c2716b1d2cb0fa87b1bfca54ff77f0d78 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:25:29 +0800
Subject: [PATCH 072/111] experiment with extra conditional nudge
---
.github/workflows/run-pytest.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index ec40982b9a..13d45f0be9 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -37,3 +37,4 @@ jobs:
run: docker exec -e DJANGO_DATABASE_URL="postgres://postgres:mathesar@localhost:5432/mathesar_django" -e MATHESAR_DATABASES="(mathesar_db_test|postgres://postgres:mathesar@localhost:5432/mathesar_db_test)" mathesar_service_test ./run_pytest.sh
tests:
needs: python_tests
+ if: ${{ success() }}
From 1c63067b5f1807392f95fcf6d655f4ff2e34b387 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:27:06 +0800
Subject: [PATCH 073/111] experiment with stronger nudge to run 'tests'
---
.github/workflows/run-pytest.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 13d45f0be9..e93aaaa5ea 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -37,4 +37,4 @@ jobs:
run: docker exec -e DJANGO_DATABASE_URL="postgres://postgres:mathesar@localhost:5432/mathesar_django" -e MATHESAR_DATABASES="(mathesar_db_test|postgres://postgres:mathesar@localhost:5432/mathesar_db_test)" mathesar_service_test ./run_pytest.sh
tests:
needs: python_tests
- if: ${{ success() }}
+ if: ${{ !failure() }}
From 17e45a6e2603cef8a01261ed099258f28316ae62 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:47:14 +0800
Subject: [PATCH 074/111] add steps to collector job
---
.github/workflows/run-pytest.yml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index e93aaaa5ea..36dc1c805b 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -36,5 +36,8 @@ jobs:
- name: Run tests with pytest
run: docker exec -e DJANGO_DATABASE_URL="postgres://postgres:mathesar@localhost:5432/mathesar_django" -e MATHESAR_DATABASES="(mathesar_db_test|postgres://postgres:mathesar@localhost:5432/mathesar_db_test)" mathesar_service_test ./run_pytest.sh
tests:
+ runs-on: ubuntu-latest
needs: python_tests
- if: ${{ !failure() }}
+ steps:
+ - name: Report success
+ run: echo "Python tests succeeded or skipped!"
From e406b49f04c6700afc30fed2975aaa8ef8008f17 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 17:48:45 +0800
Subject: [PATCH 075/111] fix syntax error (no bash conditionals?)
---
.github/workflows/run-pytest.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 36dc1c805b..28b0158833 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
# Using this construct means we'll skip to "success". This avoids the
# unrecommended path filtering in this required job.
- if: ${{ -n hashFiles('*.py', 'mathesar/**', 'db/**') }}
+ if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
strategy:
matrix:
pg-version: [13, 14, 15]
From a2843deffe72206d51ad478c3949ba3381f2415a Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 21:55:34 +0800
Subject: [PATCH 076/111] try moving check into steps
---
.github/workflows/run-pytest.yml | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 28b0158833..f65225ba01 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -7,11 +7,10 @@
name: Run Python tests
on: [pull_request, merge_group]
jobs:
- python_tests:
+ tests:
runs-on: ubuntu-latest
# Using this construct means we'll skip to "success". This avoids the
# unrecommended path filtering in this required job.
- if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
strategy:
matrix:
pg-version: [13, 14, 15]
@@ -19,25 +18,30 @@ jobs:
- uses: actions/checkout@v2
- name: Copy env file
+ if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
run: cp .env.example .env
# The code is checked out under uid 1001 - reset this to 1000 for the
# container to run tests successfully
- name: Fix permissions
+ if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
run: sudo chown -R 1000:1000 .
- name: Build the stack
+ if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
run: docker build -t mathesar_service_test --build-arg BUILD_PG_MAJOR=${{ matrix.pg-version }} --build-arg PYTHON_REQUIREMENTS=requirements-dev.txt .
env:
PG_MAJOR: ${{ matrix.pg-version }}
- name: Run docker container
+ if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
run: docker run -d --name mathesar_service_test mathesar_service_test
# Override setup.cfg docker-compose db service credentials with in built docker postgres server
- name: Run tests with pytest
+ if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
run: docker exec -e DJANGO_DATABASE_URL="postgres://postgres:mathesar@localhost:5432/mathesar_django" -e MATHESAR_DATABASES="(mathesar_db_test|postgres://postgres:mathesar@localhost:5432/mathesar_db_test)" mathesar_service_test ./run_pytest.sh
- tests:
- runs-on: ubuntu-latest
- needs: python_tests
- steps:
- - name: Report success
- run: echo "Python tests succeeded or skipped!"
+# tests:
+# runs-on: ubuntu-latest
+# needs: python_tests
+# steps:
+# - name: Report success
+# run: echo "Python tests succeeded or skipped!"
From f260d00fcb34bda8119170405153ad352c4dcaa4 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 22:42:48 +0800
Subject: [PATCH 077/111] try using 3rd party action
---
.github/workflows/run-pytest.yml | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index f65225ba01..8588e5fc32 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -7,7 +7,7 @@
name: Run Python tests
on: [pull_request, merge_group]
jobs:
- tests:
+ python_tests:
runs-on: ubuntu-latest
# Using this construct means we'll skip to "success". This avoids the
# unrecommended path filtering in this required job.
@@ -16,32 +16,40 @@ jobs:
pg-version: [13, 14, 15]
steps:
- uses: actions/checkout@v2
+ - name: Get changed files
+ id: changed_files
+ uses: tj-actions/changed-files@v39
+ with:
+ files: |
+ *.py
+ mathesar/**
+ db/**
- name: Copy env file
- if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
+ if: steps.changed_files.outputs.any_changed == 'true'
run: cp .env.example .env
# The code is checked out under uid 1001 - reset this to 1000 for the
# container to run tests successfully
- name: Fix permissions
- if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
+ if: steps.changed_files.outputs.any_changed == 'true'
run: sudo chown -R 1000:1000 .
- name: Build the stack
- if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
+ if: steps.changed_files.outputs.any_changed == 'true'
run: docker build -t mathesar_service_test --build-arg BUILD_PG_MAJOR=${{ matrix.pg-version }} --build-arg PYTHON_REQUIREMENTS=requirements-dev.txt .
env:
PG_MAJOR: ${{ matrix.pg-version }}
- name: Run docker container
- if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
+ if: steps.changed_files.outputs.any_changed == 'true'
run: docker run -d --name mathesar_service_test mathesar_service_test
# Override setup.cfg docker-compose db service credentials with in built docker postgres server
- name: Run tests with pytest
- if: ${{ hashFiles('*.py', 'mathesar/**', 'db/**') }}
+ if: steps.changed_files.outputs.any_changed == 'true'
run: docker exec -e DJANGO_DATABASE_URL="postgres://postgres:mathesar@localhost:5432/mathesar_django" -e MATHESAR_DATABASES="(mathesar_db_test|postgres://postgres:mathesar@localhost:5432/mathesar_db_test)" mathesar_service_test ./run_pytest.sh
-# tests:
-# runs-on: ubuntu-latest
-# needs: python_tests
-# steps:
-# - name: Report success
-# run: echo "Python tests succeeded or skipped!"
+ tests:
+ runs-on: ubuntu-latest
+ needs: python_tests
+ steps:
+ - name: Report success
+ run: echo "Python tests succeeded or skipped!"
From 707518eaf201748850ad61e21a86af20b5a50992 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 22:48:40 +0800
Subject: [PATCH 078/111] test tests failure
---
.github/workflows/handle-required-checks.yml | 4 ++++
mathesar/tests/api/test_table_api.py | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
index 13b60efadc..fae9a9075a 100644
--- a/.github/workflows/handle-required-checks.yml
+++ b/.github/workflows/handle-required-checks.yml
@@ -4,6 +4,10 @@
name: handle-required-checks
on: [pull_request, merge_group]
jobs:
+ tests:
+ runs-on: ubuntu-latest
+ steps:
+ - run: 'echo "No tests required"'
lint:
runs-on: ubuntu-latest
steps:
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 18df6ca1e0..1a620e6a2f 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -1679,7 +1679,7 @@ def test_table_extract_columns_retain_original_table(create_patents_table, clien
response_data = current_table_response.json()
extracted_table_id = response_data['extracted_table']
extracted_table = Table.objects.get(id=extracted_table_id)
- assert extract_table_name == extracted_table.name
+ assert extract_table_name == extracted_table.name + 'a'
remainder_table_id = response_data['remainder_table']
remainder_table = Table.objects.get(id=remainder_table_id)
assert Table.objects.filter(id=table.id).count() == 1
From ece69407421acfdffc0cea3f48f1b28de72a2ecc Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 23:15:44 +0800
Subject: [PATCH 079/111] change back to docker compose setup
---
.github/workflows/run-pytest.yml | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 8588e5fc32..99a4bac806 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -37,16 +37,14 @@ jobs:
- name: Build the stack
if: steps.changed_files.outputs.any_changed == 'true'
- run: docker build -t mathesar_service_test --build-arg BUILD_PG_MAJOR=${{ matrix.pg-version }} --build-arg PYTHON_REQUIREMENTS=requirements-dev.txt .
+ run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d test-service
env:
PG_MAJOR: ${{ matrix.pg-version }}
- - name: Run docker container
- if: steps.changed_files.outputs.any_changed == 'true'
- run: docker run -d --name mathesar_service_test mathesar_service_test
- # Override setup.cfg docker-compose db service credentials with in built docker postgres server
+
- name: Run tests with pytest
if: steps.changed_files.outputs.any_changed == 'true'
- run: docker exec -e DJANGO_DATABASE_URL="postgres://postgres:mathesar@localhost:5432/mathesar_django" -e MATHESAR_DATABASES="(mathesar_db_test|postgres://postgres:mathesar@localhost:5432/mathesar_db_test)" mathesar_service_test ./run_pytest.sh
+ run: docker exec mathesar_service_test ./run_pytest.sh
+
tests:
runs-on: ubuntu-latest
needs: python_tests
From b64ada99552630f96a0fea59318e942e9ed5d4b5 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Tue, 24 Oct 2023 23:57:33 +0800
Subject: [PATCH 080/111] test passing tests
---
mathesar/tests/api/test_table_api.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 1a620e6a2f..18df6ca1e0 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -1679,7 +1679,7 @@ def test_table_extract_columns_retain_original_table(create_patents_table, clien
response_data = current_table_response.json()
extracted_table_id = response_data['extracted_table']
extracted_table = Table.objects.get(id=extracted_table_id)
- assert extract_table_name == extracted_table.name + 'a'
+ assert extract_table_name == extracted_table.name
remainder_table_id = response_data['remainder_table']
remainder_table = Table.objects.get(id=remainder_table_id)
assert Table.objects.filter(id=table.id).count() == 1
From 61ff5bb5edfc45963fdd757385859bfc3b7632f0 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 00:14:39 +0800
Subject: [PATCH 081/111] extract pytest run trigger to separate job
---
.github/workflows/handle-required-checks.yml | 4 ---
.github/workflows/run-pytest.yml | 31 ++++++++++----------
2 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
index fae9a9075a..13b60efadc 100644
--- a/.github/workflows/handle-required-checks.yml
+++ b/.github/workflows/handle-required-checks.yml
@@ -4,10 +4,6 @@
name: handle-required-checks
on: [pull_request, merge_group]
jobs:
- tests:
- runs-on: ubuntu-latest
- steps:
- - run: 'echo "No tests required"'
lint:
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 99a4bac806..af08c9ae8c 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -7,13 +7,12 @@
name: Run Python tests
on: [pull_request, merge_group]
jobs:
- python_tests:
+ python_filechanges:
runs-on: ubuntu-latest
- # Using this construct means we'll skip to "success". This avoids the
- # unrecommended path filtering in this required job.
- strategy:
- matrix:
- pg-version: [13, 14, 15]
+ # Here, we capture whether any files have changed to indicate we need to run
+ # python tests
+ outputs:
+ any_changed: ${{ steps.changed_files.outputs.any_changed }}
steps:
- uses: actions/checkout@v2
- name: Get changed files
@@ -24,27 +23,29 @@ jobs:
*.py
mathesar/**
db/**
-
+ python_tests:
+ runs-on: ubuntu-latest
+ needs: python_filechanges
+ strategy:
+ matrix:
+ pg-version: [13, 14, 15]
+ steps:
- name: Copy env file
- if: steps.changed_files.outputs.any_changed == 'true'
+ if: needs.python_filechanges.outputs.any_changed == 'true'
run: cp .env.example .env
-
# The code is checked out under uid 1001 - reset this to 1000 for the
# container to run tests successfully
- name: Fix permissions
- if: steps.changed_files.outputs.any_changed == 'true'
+ if: needs.python_filechanges.outputs.any_changed == 'true'
run: sudo chown -R 1000:1000 .
-
- name: Build the stack
- if: steps.changed_files.outputs.any_changed == 'true'
+ if: needs.python_filechanges.outputs.any_changed == 'true'
run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d test-service
env:
PG_MAJOR: ${{ matrix.pg-version }}
-
- name: Run tests with pytest
- if: steps.changed_files.outputs.any_changed == 'true'
+ if: needs.python_filechanges.outputs.any_changed == 'true'
run: docker exec mathesar_service_test ./run_pytest.sh
-
tests:
runs-on: ubuntu-latest
needs: python_tests
From 0071bbaa83e450c4d5118d5fbf99e81844e1e11b Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 00:18:05 +0800
Subject: [PATCH 082/111] Check that tests passing works
---
mathesar/tests/api/test_table_api.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 18df6ca1e0..9ff7aafddc 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -2083,6 +2083,7 @@ def test_create_table_using_duplicate_id_excel_data_file(client, duplicate_id_ex
def test_create_table_using_null_id_excel_data_file(client, null_id_excel_data_file, schema):
+ # silly comment
table_name = 'null_id'
expt_name = get_expected_name(table_name, data_file=null_id_excel_data_file)
first_row = (1, '1.0', 'John', '25')
From 04b843f59f2412fb7710c1106fb92702b8f032ad Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 00:41:23 +0800
Subject: [PATCH 083/111] restore the checkout for testing
---
.github/workflows/run-pytest.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index af08c9ae8c..bce88de1dc 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -30,6 +30,7 @@ jobs:
matrix:
pg-version: [13, 14, 15]
steps:
+ - uses: actions/checkout@v2
- name: Copy env file
if: needs.python_filechanges.outputs.any_changed == 'true'
run: cp .env.example .env
From f1c65b5a6a7f5ecdbc060ab0a51d45bab8c04ed5 Mon Sep 17 00:00:00 2001
From: pavish
Date: Tue, 24 Oct 2023 22:17:36 +0530
Subject: [PATCH 084/111] Fix types
---
.../linked-record/LinkedRecordCell.svelte | 6 ++---
.../data-types/components/typeDefinitions.ts | 23 +++++++++++++++++--
.../cell-fabric/data-types/typeDefinitions.ts | 13 +++++------
.../src/components/cell-fabric/types.ts | 14 ++++-------
.../src/stores/table-data/processedColumns.ts | 11 +--------
5 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
index 78948cf0ea..4f115834f3 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/linked-record/LinkedRecordCell.svelte
@@ -42,10 +42,10 @@
}
event?.stopPropagation();
const result = await recordSelector.acquireUserInput({ tableId });
- const LinkedFkCellValue = columnFabric.linkFk?.referent_columns[0];
+ const linkedFkColumnId = columnFabric.linkFk?.referent_columns[0];
if (result) {
- if (LinkedFkCellValue !== undefined && LinkedFkCellValue !== null) {
- value = result.record[LinkedFkCellValue];
+ if (linkedFkColumnId) {
+ value = result.record[linkedFkColumnId];
} else {
value = result.recordId;
}
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts b/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts
index b510849dcd..5e3269c103 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts
+++ b/mathesar_ui/src/components/cell-fabric/data-types/components/typeDefinitions.ts
@@ -2,10 +2,29 @@ import type {
FormattedInputProps,
NumberFormatterOptions,
SelectProps,
+ ComponentAndProps,
} from '@mathesar-component-library/types';
-import type { ProcessedColumn } from '@mathesar/stores/table-data/processedColumns';
import type { DBObjectEntry } from '@mathesar/AppTypes';
import type { DateTimeFormatter } from '@mathesar/utils/date-time/types';
+import type { Column } from '@mathesar/api/types/tables/columns';
+import type { FkConstraint } from '@mathesar/api/types/tables/constraints';
+
+export type CellColumnLike = Pick<
+ Column,
+ 'type' | 'type_options' | 'display_options'
+>;
+
+export interface CellColumnFabric {
+ id: string | number;
+ column: CellColumnLike;
+ /**
+ * Present when the column has one single-column FK constraint. In the
+ * unlikely (but theoretically possible) scenario that this column has more
+ * than one FK constraint, the first FK constraint is referenced.
+ */
+ linkFk?: FkConstraint;
+ cellComponentAndProps: ComponentAndProps;
+}
export type CellValueFormatter = (
value: T | null | undefined,
@@ -46,7 +65,7 @@ export interface LinkedRecordCellExternalProps {
export interface LinkedRecordCellProps
extends CellTypeProps,
LinkedRecordCellExternalProps {
- columnFabric: ProcessedColumn;
+ columnFabric: CellColumnFabric;
recordSummary?: string;
setRecordSummary?: (recordId: string, recordSummary: string) => void;
}
diff --git a/mathesar_ui/src/components/cell-fabric/data-types/typeDefinitions.ts b/mathesar_ui/src/components/cell-fabric/data-types/typeDefinitions.ts
index b3b07b7b54..b066f67896 100644
--- a/mathesar_ui/src/components/cell-fabric/data-types/typeDefinitions.ts
+++ b/mathesar_ui/src/components/cell-fabric/data-types/typeDefinitions.ts
@@ -1,6 +1,10 @@
-import type { Column } from '@mathesar/api/types/tables/columns';
import type { ComponentAndProps } from '@mathesar-component-library/types';
-import type { CellValueFormatter } from './components/typeDefinitions';
+import type {
+ CellValueFormatter,
+ CellColumnLike as CellColumnLikeInner,
+} from './components/typeDefinitions';
+
+export type CellColumnLike = CellColumnLikeInner;
// The types here are frontend types and are
// different from db types.
@@ -20,11 +24,6 @@ export type CompoundCellDataTypes = 'array';
export type CellDataType = SimpleCellDataTypes | CompoundCellDataTypes;
-export type CellColumnLike = Pick<
- Column,
- 'type' | 'type_options' | 'display_options'
->;
-
export interface CellComponentFactory {
initialInputValue?: unknown;
get(
diff --git a/mathesar_ui/src/components/cell-fabric/types.ts b/mathesar_ui/src/components/cell-fabric/types.ts
index f824c31ed1..c1c3c7fb9b 100644
--- a/mathesar_ui/src/components/cell-fabric/types.ts
+++ b/mathesar_ui/src/components/cell-fabric/types.ts
@@ -1,10 +1,4 @@
-import type { ComponentAndProps } from '@mathesar-component-library/types';
-import type { CellColumnLike } from './data-types/typeDefinitions';
-
-export interface CellColumnFabric {
- id: string | number;
- column: CellColumnLike;
- cellComponentAndProps: ComponentAndProps;
-}
-
-export type { CellValueFormatter } from './data-types/components/typeDefinitions';
+export type {
+ CellColumnFabric,
+ CellValueFormatter,
+} from './data-types/components/typeDefinitions';
diff --git a/mathesar_ui/src/stores/table-data/processedColumns.ts b/mathesar_ui/src/stores/table-data/processedColumns.ts
index 7fc3a907fb..a863bd58cb 100644
--- a/mathesar_ui/src/stores/table-data/processedColumns.ts
+++ b/mathesar_ui/src/stores/table-data/processedColumns.ts
@@ -1,10 +1,7 @@
import type { ComponentAndProps } from '@mathesar-component-library/types';
import type { TableEntry } from '@mathesar/api/types/tables';
import type { Column } from '@mathesar/api/types/tables/columns';
-import type {
- Constraint,
- FkConstraint,
-} from '@mathesar/api/types/tables/constraints';
+import type { Constraint } from '@mathesar/api/types/tables/constraints';
import type { CellColumnFabric } from '@mathesar/components/cell-fabric/types';
import {
getCellCap,
@@ -39,12 +36,6 @@ export interface ProcessedColumn extends CellColumnFabric {
exclusiveConstraints: Constraint[];
/** Constraints whose columns include this column and other columns too */
sharedConstraints: Constraint[];
- /**
- * Present when this column has one single-column FK constraint. In the
- * unlikely (but theoretically possible) scenario that this column has more
- * than one FK constraint, the first FK constraint is used.
- */
- linkFk: FkConstraint | undefined;
abstractType: AbstractType;
initialInputValue: unknown;
inputComponentAndProps: ComponentAndProps;
From 37ec26dd5a88d72d852c8bd56db293e934fc3e66 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 16:00:53 +0800
Subject: [PATCH 085/111] attempt to avoid stepwise if checks
---
.github/workflows/run-pytest.yml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index bce88de1dc..6503a6c58d 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -26,26 +26,23 @@ jobs:
python_tests:
runs-on: ubuntu-latest
needs: python_filechanges
+ if: needs.python_filechanges.outputs.any_changed == 'true'
strategy:
matrix:
pg-version: [13, 14, 15]
steps:
- uses: actions/checkout@v2
- name: Copy env file
- if: needs.python_filechanges.outputs.any_changed == 'true'
run: cp .env.example .env
# The code is checked out under uid 1001 - reset this to 1000 for the
# container to run tests successfully
- name: Fix permissions
- if: needs.python_filechanges.outputs.any_changed == 'true'
run: sudo chown -R 1000:1000 .
- name: Build the stack
- if: needs.python_filechanges.outputs.any_changed == 'true'
run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d test-service
env:
PG_MAJOR: ${{ matrix.pg-version }}
- name: Run tests with pytest
- if: needs.python_filechanges.outputs.any_changed == 'true'
run: docker exec mathesar_service_test ./run_pytest.sh
tests:
runs-on: ubuntu-latest
From d1ef2851ef056da0c895eb283e2942b4306fcabe Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 16:04:29 +0800
Subject: [PATCH 086/111] test behavior when no py changes
---
mathesar/tests/api/test_table_api.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 9ff7aafddc..18df6ca1e0 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -2083,7 +2083,6 @@ def test_create_table_using_duplicate_id_excel_data_file(client, duplicate_id_ex
def test_create_table_using_null_id_excel_data_file(client, null_id_excel_data_file, schema):
- # silly comment
table_name = 'null_id'
expt_name = get_expected_name(table_name, data_file=null_id_excel_data_file)
first_row = (1, '1.0', 'John', '25')
From db420fd41fbd72f64c8bb44af2291fd885d3a0e2 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 16:09:04 +0800
Subject: [PATCH 087/111] See whether matrix strategy still counts as a pass
---
.github/workflows/run-pytest.yml | 14 +++++++-------
mathesar/tests/api/test_table_api.py | 1 +
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 6503a6c58d..7af81c665b 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -23,7 +23,7 @@ jobs:
*.py
mathesar/**
db/**
- python_tests:
+ tests:
runs-on: ubuntu-latest
needs: python_filechanges
if: needs.python_filechanges.outputs.any_changed == 'true'
@@ -44,9 +44,9 @@ jobs:
PG_MAJOR: ${{ matrix.pg-version }}
- name: Run tests with pytest
run: docker exec mathesar_service_test ./run_pytest.sh
- tests:
- runs-on: ubuntu-latest
- needs: python_tests
- steps:
- - name: Report success
- run: echo "Python tests succeeded or skipped!"
+# tests:
+# runs-on: ubuntu-latest
+# needs: python_tests
+# steps:
+# - name: Report success
+# run: echo "Python tests succeeded or skipped!"
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 18df6ca1e0..9ff7aafddc 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -2083,6 +2083,7 @@ def test_create_table_using_duplicate_id_excel_data_file(client, duplicate_id_ex
def test_create_table_using_null_id_excel_data_file(client, null_id_excel_data_file, schema):
+ # silly comment
table_name = 'null_id'
expt_name = get_expected_name(table_name, data_file=null_id_excel_data_file)
first_row = (1, '1.0', 'John', '25')
From e7615b7cb8bba4569471be64a46379e4cbd3d640 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 16:36:15 +0800
Subject: [PATCH 088/111] revert experiment, update action version
---
.github/workflows/run-pytest.yml | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 7af81c665b..3f10b38fcd 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -14,7 +14,7 @@ jobs:
outputs:
any_changed: ${{ steps.changed_files.outputs.any_changed }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Get changed files
id: changed_files
uses: tj-actions/changed-files@v39
@@ -23,7 +23,7 @@ jobs:
*.py
mathesar/**
db/**
- tests:
+ python_tests:
runs-on: ubuntu-latest
needs: python_filechanges
if: needs.python_filechanges.outputs.any_changed == 'true'
@@ -44,9 +44,9 @@ jobs:
PG_MAJOR: ${{ matrix.pg-version }}
- name: Run tests with pytest
run: docker exec mathesar_service_test ./run_pytest.sh
-# tests:
-# runs-on: ubuntu-latest
-# needs: python_tests
-# steps:
-# - name: Report success
-# run: echo "Python tests succeeded or skipped!"
+ tests:
+ runs-on: ubuntu-latest
+ needs: python_tests
+ steps:
+ - name: Report success
+ run: echo "Python tests succeeded or skipped!"
From 0e3de338a33cbd7a3003a75b8e75fabc5ec276d4 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 17:01:30 +0800
Subject: [PATCH 089/111] use new setup for python linting
---
.github/workflows/handle-required-checks.yml | 7 ----
.github/workflows/run-flake8.yml | 27 -------------
.github/workflows/run-pytest.yml | 40 ++++++++++++++++++--
3 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
index 13b60efadc..d5962e1a77 100644
--- a/.github/workflows/handle-required-checks.yml
+++ b/.github/workflows/handle-required-checks.yml
@@ -1,10 +1,3 @@
## "lint" and "tests" are required checks, but they run conditionally.
## This handles the cases where they don't run because no Python or JS file has been changed.
## See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
-name: handle-required-checks
-on: [pull_request, merge_group]
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - run: 'echo "No lint required"'
diff --git a/.github/workflows/run-flake8.yml b/.github/workflows/run-flake8.yml
index 98eba2706c..e69de29bb2 100644
--- a/.github/workflows/run-flake8.yml
+++ b/.github/workflows/run-flake8.yml
@@ -1,27 +0,0 @@
-name: Lint Python code
-
-on:
- push:
- paths:
- - '**.py'
- pull_request:
- paths:
- - '**.py'
-
-jobs:
- lint:
- runs-on: ubuntu-latest
- # We only want to run on external PRs, since internal PRs are covered by "push"
- # This prevents this from running twice on internal PRs
- if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
- - name: Run flake8
- uses: julianwachholz/flake8-action@main
- with:
- checkName: "flake8"
- path: "."
- plugins: flake8-no-types
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 3f10b38fcd..108035a1b3 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -7,7 +7,7 @@
name: Run Python tests
on: [pull_request, merge_group]
jobs:
- python_filechanges:
+ pytest_required_check:
runs-on: ubuntu-latest
# Here, we capture whether any files have changed to indicate we need to run
# python tests
@@ -23,10 +23,26 @@ jobs:
*.py
mathesar/**
db/**
+
+ flake8_required_check:
+ runs-on: ubuntu-latest
+ # Here, we capture whether any files have changed to indicate we need to run
+ # python tests
+ outputs:
+ any_changed: ${{ steps.changed_files.outputs.any_changed }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Get changed files
+ id: changed_files
+ uses: tj-actions/changed-files@v39
+ with:
+ files: '**.py'
+
python_tests:
+ name: Run Python tests
runs-on: ubuntu-latest
- needs: python_filechanges
- if: needs.python_filechanges.outputs.any_changed == 'true'
+ needs: pytest_required_check
+ if: needs.pytest_required_check.outputs.any_changed == 'true'
strategy:
matrix:
pg-version: [13, 14, 15]
@@ -44,6 +60,24 @@ jobs:
PG_MAJOR: ${{ matrix.pg-version }}
- name: Run tests with pytest
run: docker exec mathesar_service_test ./run_pytest.sh
+
+ lint:
+ name: Lint Python code
+ runs-on: ubuntu-latest
+ needs: flake8_required_check
+ if: needs.flake8_required_check.outputs.any_changed == 'true'
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v4
+ - name: Run flake8
+ uses: julianwachholz/flake8-action@main
+ with:
+ checkName: "flake8"
+ path: "."
+ plugins: flake8-no-types
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
tests:
runs-on: ubuntu-latest
needs: python_tests
From 371a8c4060ae473d037d9aceb591bca7a73e2362 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 17:10:33 +0800
Subject: [PATCH 090/111] check if there's a problem due to custom name
---
.github/workflows/run-pytest.yml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 108035a1b3..e94d460335 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -62,7 +62,6 @@ jobs:
run: docker exec mathesar_service_test ./run_pytest.sh
lint:
- name: Lint Python code
runs-on: ubuntu-latest
needs: flake8_required_check
if: needs.flake8_required_check.outputs.any_changed == 'true'
From 937f8f92ace409f2fcc0cb4429cf49b8807921e3 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 17:22:55 +0800
Subject: [PATCH 091/111] double-check that giving the job a name breaks the
status check
---
.github/workflows/run-pytest.yml | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index e94d460335..6ce9974335 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -20,9 +20,10 @@ jobs:
uses: tj-actions/changed-files@v39
with:
files: |
- *.py
- mathesar/**
- db/**
+ *.abcde
+# *.py
+# mathesar/**
+# db/**
flake8_required_check:
runs-on: ubuntu-latest
@@ -47,7 +48,7 @@ jobs:
matrix:
pg-version: [13, 14, 15]
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Copy env file
run: cp .env.example .env
# The code is checked out under uid 1001 - reset this to 1000 for the
@@ -62,6 +63,7 @@ jobs:
run: docker exec mathesar_service_test ./run_pytest.sh
lint:
+ name: Run Python linter
runs-on: ubuntu-latest
needs: flake8_required_check
if: needs.flake8_required_check.outputs.any_changed == 'true'
From 981b4027274645187e3fba92f71d6ed8806cf97e Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 17:40:49 +0800
Subject: [PATCH 092/111] clean up, remove cruft, rename file
---
.github/workflows/handle-required-checks.yml | 3 ---
.github/workflows/run-flake8.yml | 0
.../workflows/{run-pytest.yml => run-lint-tests-py.yml} | 9 ++++++++-
3 files changed, 8 insertions(+), 4 deletions(-)
delete mode 100644 .github/workflows/handle-required-checks.yml
delete mode 100644 .github/workflows/run-flake8.yml
rename .github/workflows/{run-pytest.yml => run-lint-tests-py.yml} (94%)
diff --git a/.github/workflows/handle-required-checks.yml b/.github/workflows/handle-required-checks.yml
deleted file mode 100644
index d5962e1a77..0000000000
--- a/.github/workflows/handle-required-checks.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-## "lint" and "tests" are required checks, but they run conditionally.
-## This handles the cases where they don't run because no Python or JS file has been changed.
-## See https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
diff --git a/.github/workflows/run-flake8.yml b/.github/workflows/run-flake8.yml
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-lint-tests-py.yml
similarity index 94%
rename from .github/workflows/run-pytest.yml
rename to .github/workflows/run-lint-tests-py.yml
index 6ce9974335..f0661f51e4 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-lint-tests-py.yml
@@ -62,7 +62,7 @@ jobs:
- name: Run tests with pytest
run: docker exec mathesar_service_test ./run_pytest.sh
- lint:
+ python_lint:
name: Run Python linter
runs-on: ubuntu-latest
needs: flake8_required_check
@@ -85,3 +85,10 @@ jobs:
steps:
- name: Report success
run: echo "Python tests succeeded or skipped!"
+
+ lint:
+ runs-on: ubuntu-latest
+ needs: python_lint
+ steps:
+ - name: Report success
+ run: echo "Python linter succeeded or skipped!"
From 83aee3daa2f047ad87b9fd2381a4e26bd3d96ea7 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 17:54:56 +0800
Subject: [PATCH 093/111] add SQL tests to backend test yml
---
.github/workflows/run-lint-tests-py.yml | 48 ++++++++++++++++++++-----
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/run-lint-tests-py.yml b/.github/workflows/run-lint-tests-py.yml
index f0661f51e4..40ba69269e 100644
--- a/.github/workflows/run-lint-tests-py.yml
+++ b/.github/workflows/run-lint-tests-py.yml
@@ -4,7 +4,7 @@
# that runs status checks and reports them whenever a PR is added to the merge
# queue.
-name: Run Python tests
+name: Backend tests and linting
on: [pull_request, merge_group]
jobs:
pytest_required_check:
@@ -20,10 +20,9 @@ jobs:
uses: tj-actions/changed-files@v39
with:
files: |
- *.abcde
-# *.py
-# mathesar/**
-# db/**
+ *.py
+ mathesar/**
+ db/**
flake8_required_check:
runs-on: ubuntu-latest
@@ -39,6 +38,20 @@ jobs:
with:
files: '**.py'
+ sql_tests_required_check:
+ runs-on: ubuntu-latest
+ # Here, we capture whether any files have changed to indicate we need to run
+ # python tests
+ outputs:
+ any_changed: ${{ steps.changed_files.outputs.any_changed }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Get changed files
+ id: changed_files
+ uses: tj-actions/changed-files@v39
+ with:
+ files: '**.sql'
+
python_tests:
name: Run Python tests
runs-on: ubuntu-latest
@@ -58,10 +71,29 @@ jobs:
- name: Build the stack
run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d test-service
env:
- PG_MAJOR: ${{ matrix.pg-version }}
+ PG_VERSION: ${{ matrix.pg-version }}
- name: Run tests with pytest
run: docker exec mathesar_service_test ./run_pytest.sh
+ sql_tests:
+ runs-on: ubuntu-latest
+ if: needs.sql_tests_required_check.outputs.any_changed == 'true'
+ strategy:
+ matrix:
+ pg-version: [13, 14, 15]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Copy env file
+ run: cp .env.example .env
+ - name: Fix permissions
+ run: sudo chown -R 1000:1000 .
+ - name: Build the test DB
+ run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d dev-db
+ env:
+ PG_VERSION: ${{ matrix.pg-version }}
+ - name: Run tests with pg_prove
+ run: docker exec mathesar_dev_db /bin/bash /sql/run_tests.sh
+
python_lint:
name: Run Python linter
runs-on: ubuntu-latest
@@ -81,10 +113,10 @@ jobs:
tests:
runs-on: ubuntu-latest
- needs: python_tests
+ needs: python_tests, sql_tests
steps:
- name: Report success
- run: echo "Python tests succeeded or skipped!"
+ run: echo "Backend tests succeeded or skipped!"
lint:
runs-on: ubuntu-latest
From 0a75055e95e056a20a6e9f7eaaa88742b58daed5 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 18:00:56 +0800
Subject: [PATCH 094/111] fix syntax error in workflow file
---
.github/workflows/run-lint-tests-py.yml | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/run-lint-tests-py.yml b/.github/workflows/run-lint-tests-py.yml
index 40ba69269e..6e7673261e 100644
--- a/.github/workflows/run-lint-tests-py.yml
+++ b/.github/workflows/run-lint-tests-py.yml
@@ -27,7 +27,7 @@ jobs:
flake8_required_check:
runs-on: ubuntu-latest
# Here, we capture whether any files have changed to indicate we need to run
- # python tests
+ # python linter
outputs:
any_changed: ${{ steps.changed_files.outputs.any_changed }}
steps:
@@ -41,7 +41,7 @@ jobs:
sql_tests_required_check:
runs-on: ubuntu-latest
# Here, we capture whether any files have changed to indicate we need to run
- # python tests
+ # SQL tests
outputs:
any_changed: ${{ steps.changed_files.outputs.any_changed }}
steps:
@@ -76,6 +76,7 @@ jobs:
run: docker exec mathesar_service_test ./run_pytest.sh
sql_tests:
+ name: Run SQL tests
runs-on: ubuntu-latest
if: needs.sql_tests_required_check.outputs.any_changed == 'true'
strategy:
@@ -113,7 +114,7 @@ jobs:
tests:
runs-on: ubuntu-latest
- needs: python_tests, sql_tests
+ needs: [python_tests, sql_tests]
steps:
- name: Report success
run: echo "Backend tests succeeded or skipped!"
From fbd7711683c0766619948b601ad8b4eab1edfc37 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 18:06:12 +0800
Subject: [PATCH 095/111] Test pipeline fails when SQL tests fail
---
.github/workflows/run-sql-tests.yml | 37 -----------------------------
db/sql/test_0_msar.sql | 2 +-
2 files changed, 1 insertion(+), 38 deletions(-)
delete mode 100644 .github/workflows/run-sql-tests.yml
diff --git a/.github/workflows/run-sql-tests.yml b/.github/workflows/run-sql-tests.yml
deleted file mode 100644
index d5761bc3ab..0000000000
--- a/.github/workflows/run-sql-tests.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: Run SQL tests
-on:
- push:
- paths:
- - '**.sql'
- pull_request:
- paths:
- - '**.sql'
-
-
-jobs:
- tests:
- runs-on: ubuntu-latest
- # We only want to run on external PRs, since internal PRs are covered by "push"
- # This prevents this from running twice on internal PRs
- if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
- strategy:
- matrix:
- pg-version: [13, 14, 15]
- steps:
- - uses: actions/checkout@v2
-
- - name: Copy env file
- run: cp .env.example .env
-
- # The code is checked out under uid 1001 - reset this to 1000 for the
- # container to run tests successfully
- - name: Fix permissions
- run: sudo chown -R 1000:1000 .
-
- - name: Build the test DB
- run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d dev-db
- env:
- PG_VERSION: ${{ matrix.pg-version }}
-
- - name: Run tests with pg_prove
- run: docker exec mathesar_dev_db /bin/bash /sql/run_tests.sh
diff --git a/db/sql/test_0_msar.sql b/db/sql/test_0_msar.sql
index 659070202b..ce7fddb121 100644
--- a/db/sql/test_0_msar.sql
+++ b/db/sql/test_0_msar.sql
@@ -463,7 +463,7 @@ BEGIN
PERFORM msar.copy_column(
'copy_coltest'::regclass::oid, 2::smallint, 'col1 supercopy', true, true
);
- RETURN NEXT col_type_is('copy_coltest', 'col1 supercopy', 'character varying');
+ RETURN NEXT col_type_is('copy_coltest', 'col1 supercopy', 'character vrying');
RETURN NEXT col_is_null('copy_coltest', 'col1 supercopy');
RETURN NEXT col_is_unique('copy_coltest', ARRAY['col1', 'col2']);
RETURN NEXT col_is_unique('copy_coltest', ARRAY['col1 supercopy', 'col2']);
From ee2748155477396ea56a4b834a11eecadf193c5f Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 18:14:00 +0800
Subject: [PATCH 096/111] set python tests to skip, fix SQL job bug
---
.github/workflows/run-lint-tests-py.yml | 1 +
mathesar/tests/api/test_table_api.py | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/run-lint-tests-py.yml b/.github/workflows/run-lint-tests-py.yml
index 6e7673261e..a54c51ff54 100644
--- a/.github/workflows/run-lint-tests-py.yml
+++ b/.github/workflows/run-lint-tests-py.yml
@@ -78,6 +78,7 @@ jobs:
sql_tests:
name: Run SQL tests
runs-on: ubuntu-latest
+ needs: sql_tests_required_check
if: needs.sql_tests_required_check.outputs.any_changed == 'true'
strategy:
matrix:
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 9ff7aafddc..18df6ca1e0 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -2083,7 +2083,6 @@ def test_create_table_using_duplicate_id_excel_data_file(client, duplicate_id_ex
def test_create_table_using_null_id_excel_data_file(client, null_id_excel_data_file, schema):
- # silly comment
table_name = 'null_id'
expt_name = get_expected_name(table_name, data_file=null_id_excel_data_file)
first_row = (1, '1.0', 'John', '25')
From 16c3c3256c5aeb15c6d59417777e1f30c7ccda4f Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 21:37:10 +0800
Subject: [PATCH 097/111] check behavior when all tests are skipped
---
db/sql/test_0_msar.sql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/db/sql/test_0_msar.sql b/db/sql/test_0_msar.sql
index ce7fddb121..659070202b 100644
--- a/db/sql/test_0_msar.sql
+++ b/db/sql/test_0_msar.sql
@@ -463,7 +463,7 @@ BEGIN
PERFORM msar.copy_column(
'copy_coltest'::regclass::oid, 2::smallint, 'col1 supercopy', true, true
);
- RETURN NEXT col_type_is('copy_coltest', 'col1 supercopy', 'character vrying');
+ RETURN NEXT col_type_is('copy_coltest', 'col1 supercopy', 'character varying');
RETURN NEXT col_is_null('copy_coltest', 'col1 supercopy');
RETURN NEXT col_is_unique('copy_coltest', ARRAY['col1', 'col2']);
RETURN NEXT col_is_unique('copy_coltest', ARRAY['col1 supercopy', 'col2']);
From cfcaf2f64c45fd6e6c333d2321317309d8a1c425 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 21:48:43 +0800
Subject: [PATCH 098/111] Move vulture job into main backend file
also add .py change for testing
---
...nt-tests-py.yml => backend-validation.yml} | 16 +++++++++++--
.github/workflows/run-vulture.yml | 23 -------------------
mathesar/tests/api/test_table_api.py | 1 +
3 files changed, 15 insertions(+), 25 deletions(-)
rename .github/workflows/{run-lint-tests-py.yml => backend-validation.yml} (90%)
delete mode 100644 .github/workflows/run-vulture.yml
diff --git a/.github/workflows/run-lint-tests-py.yml b/.github/workflows/backend-validation.yml
similarity index 90%
rename from .github/workflows/run-lint-tests-py.yml
rename to .github/workflows/backend-validation.yml
index a54c51ff54..2a4fb35cb7 100644
--- a/.github/workflows/run-lint-tests-py.yml
+++ b/.github/workflows/backend-validation.yml
@@ -24,7 +24,7 @@ jobs:
mathesar/**
db/**
- flake8_required_check:
+ python_lint_required_check:
runs-on: ubuntu-latest
# Here, we capture whether any files have changed to indicate we need to run
# python linter
@@ -52,6 +52,18 @@ jobs:
with:
files: '**.sql'
+ vulture:
+ runs-on: ubuntu-latest
+ name: Find unused code
+ if: needs.python_lint_required_check.outputs.any_changed == 'true'
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v4
+ - name: Install Vulture
+ run: pip3 install vulture
+ - name: Run Vulture
+ run: vulture .
+
python_tests:
name: Run Python tests
runs-on: ubuntu-latest
@@ -100,7 +112,7 @@ jobs:
name: Run Python linter
runs-on: ubuntu-latest
needs: flake8_required_check
- if: needs.flake8_required_check.outputs.any_changed == 'true'
+ if: needs.python_lint_required_check.outputs.any_changed == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
diff --git a/.github/workflows/run-vulture.yml b/.github/workflows/run-vulture.yml
deleted file mode 100644
index b4533aedb0..0000000000
--- a/.github/workflows/run-vulture.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: Find unused code
-
-on:
- push:
- paths:
- - '**.py'
- pull_request:
- paths:
- - '**.py'
-
-jobs:
- build:
- runs-on: ubuntu-latest
- # We only want to run on external PRs, since internal PRs are covered by "push"
- # This prevents this from running twice on internal PRs
- if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
- - name: Install Vulture
- run: pip3 install vulture
- - name: Run Vulture
- run: vulture .
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 18df6ca1e0..9ff7aafddc 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -2083,6 +2083,7 @@ def test_create_table_using_duplicate_id_excel_data_file(client, duplicate_id_ex
def test_create_table_using_null_id_excel_data_file(client, null_id_excel_data_file, schema):
+ # silly comment
table_name = 'null_id'
expt_name = get_expected_name(table_name, data_file=null_id_excel_data_file)
first_row = (1, '1.0', 'John', '25')
From b5806d432519d559dca18d993ac5c2e8b9da2b5e Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Wed, 25 Oct 2023 22:32:54 +0800
Subject: [PATCH 099/111] fix misnamed dependency, reorganize
---
.github/workflows/backend-validation.yml | 27 ++++++++++++------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/backend-validation.yml b/.github/workflows/backend-validation.yml
index 2a4fb35cb7..bb9b8174ae 100644
--- a/.github/workflows/backend-validation.yml
+++ b/.github/workflows/backend-validation.yml
@@ -52,18 +52,6 @@ jobs:
with:
files: '**.sql'
- vulture:
- runs-on: ubuntu-latest
- name: Find unused code
- if: needs.python_lint_required_check.outputs.any_changed == 'true'
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v4
- - name: Install Vulture
- run: pip3 install vulture
- - name: Run Vulture
- run: vulture .
-
python_tests:
name: Run Python tests
runs-on: ubuntu-latest
@@ -111,7 +99,7 @@ jobs:
python_lint:
name: Run Python linter
runs-on: ubuntu-latest
- needs: flake8_required_check
+ needs: python_lint_required_check
if: needs.python_lint_required_check.outputs.any_changed == 'true'
steps:
- uses: actions/checkout@v4
@@ -125,6 +113,19 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ vulture:
+ name: Find unused code
+ runs-on: ubuntu-latest
+ needs: python_lint_required_check
+ if: needs.python_lint_required_check.outputs.any_changed == 'true'
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v4
+ - name: Install Vulture
+ run: pip3 install vulture
+ - name: Run Vulture
+ run: vulture .
+
tests:
runs-on: ubuntu-latest
needs: [python_tests, sql_tests]
From 825a36f7f15be5650c550b9bd395a9441421b953 Mon Sep 17 00:00:00 2001
From: Sean Colsen
Date: Wed, 25 Oct 2023 13:35:18 -0400
Subject: [PATCH 100/111] Resolve conflicting migrations
---
mathesar/migrations/0009_merge_20231025_1733.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 mathesar/migrations/0009_merge_20231025_1733.py
diff --git a/mathesar/migrations/0009_merge_20231025_1733.py b/mathesar/migrations/0009_merge_20231025_1733.py
new file mode 100644
index 0000000000..83e79e46ad
--- /dev/null
+++ b/mathesar/migrations/0009_merge_20231025_1733.py
@@ -0,0 +1,14 @@
+# Generated by Django 3.1.14 on 2023-10-25 17:33
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mathesar', '0008_auto_20230921_1834'),
+ ('mathesar', '0005_user_display_language'),
+ ]
+
+ operations = [
+ ]
From 069bdd62732f3126c7a1f84c4791e2995e879a34 Mon Sep 17 00:00:00 2001
From: Evyn
Date: Thu, 26 Oct 2023 08:24:39 +1000
Subject: [PATCH 101/111] Display more accurate infoAlertText on foreign key
columns
Update the displayed text to be more accurate, not mentioning primary
keys specifically.
---
.../systems/table-view/table-inspector/column/ColumnType.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mathesar_ui/src/systems/table-view/table-inspector/column/ColumnType.svelte b/mathesar_ui/src/systems/table-view/table-inspector/column/ColumnType.svelte
index 3b29cb72e8..562d354b60 100644
--- a/mathesar_ui/src/systems/table-view/table-inspector/column/ColumnType.svelte
+++ b/mathesar_ui/src/systems/table-view/table-inspector/column/ColumnType.svelte
@@ -35,7 +35,7 @@
return 'The data type of the primary key column is restricted and cannot be changed.';
}
if (column.linkFk) {
- return 'The data type of the foreign key column is restricted to the data type of the primary key column and cannot be changed.';
+ return 'The data type of this column must match the referenced column and cannot be changed.';
}
return '';
})();
From 6c3439bf1e18fdde14da92983586938a1814dac5 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 15:02:21 +0800
Subject: [PATCH 102/111] Clean up workflow file, add documenting comments
---
.github/workflows/backend-validation.yml | 61 ++++++++++++++++--------
mathesar/tests/api/test_table_api.py | 1 -
2 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/.github/workflows/backend-validation.yml b/.github/workflows/backend-validation.yml
index bb9b8174ae..97f1823e69 100644
--- a/.github/workflows/backend-validation.yml
+++ b/.github/workflows/backend-validation.yml
@@ -7,12 +7,22 @@
name: Backend tests and linting
on: [pull_request, merge_group]
jobs:
- pytest_required_check:
+
+################################################################################
+## FILE CHANGE CHECKERS ##
+## ##
+## These jobs check which files have changed so that we can call appropriate ##
+## testing, auditing, and linting jobs. Jobs in this section should check for ##
+## file changes that would indicate whether we need to run some particular ##
+## test suite, then they should output 'true' if such file changes are found. ##
+## ##
+################################################################################
+
+ python_tests_required:
+ name: Check for file changes requiring python tests
runs-on: ubuntu-latest
- # Here, we capture whether any files have changed to indicate we need to run
- # python tests
outputs:
- any_changed: ${{ steps.changed_files.outputs.any_changed }}
+ tests_should_run: ${{ steps.changed_files.outputs.any_changed }}
steps:
- uses: actions/checkout@v4
- name: Get changed files
@@ -24,12 +34,11 @@ jobs:
mathesar/**
db/**
- python_lint_required_check:
+ python_lint_required:
+ name: Check for file changes requiring python linter
runs-on: ubuntu-latest
- # Here, we capture whether any files have changed to indicate we need to run
- # python linter
outputs:
- any_changed: ${{ steps.changed_files.outputs.any_changed }}
+ lint_should_run: ${{ steps.changed_files.outputs.any_changed }}
steps:
- uses: actions/checkout@v4
- name: Get changed files
@@ -38,12 +47,11 @@ jobs:
with:
files: '**.py'
- sql_tests_required_check:
+ sql_tests_required:
+ name: Check for file changes requiring SQL tests
runs-on: ubuntu-latest
- # Here, we capture whether any files have changed to indicate we need to run
- # SQL tests
outputs:
- any_changed: ${{ steps.changed_files.outputs.any_changed }}
+ tests_should_run: ${{ steps.changed_files.outputs.any_changed }}
steps:
- uses: actions/checkout@v4
- name: Get changed files
@@ -52,11 +60,24 @@ jobs:
with:
files: '**.sql'
+################################################################################
+## TEST/LINT RUNNERS ##
+## ##
+## These jobs run tests and linters. Each job in this section should be ##
+## dependent on one of the FILE CHANGE CHECKERS above, and should only run if ##
+## appropriate files have changed. You can see this by using a `needs:` block ##
+## to make the job dependent on the relevant file checker, and an `if:` block ##
+## to ensure that the file checker returned 'true' before running the actual ##
+## job. Job IDs in this section must be namespaced (so `python_tests` ##
+## instead of just `tests`). ##
+## ##
+################################################################################
+
python_tests:
name: Run Python tests
runs-on: ubuntu-latest
- needs: pytest_required_check
- if: needs.pytest_required_check.outputs.any_changed == 'true'
+ needs: python_tests_required
+ if: needs.python_tests_required.outputs.tests_should_run == 'true'
strategy:
matrix:
pg-version: [13, 14, 15]
@@ -79,7 +100,7 @@ jobs:
name: Run SQL tests
runs-on: ubuntu-latest
needs: sql_tests_required_check
- if: needs.sql_tests_required_check.outputs.any_changed == 'true'
+ if: needs.sql_tests_required.outputs.tests_should_run == 'true'
strategy:
matrix:
pg-version: [13, 14, 15]
@@ -87,6 +108,8 @@ jobs:
- uses: actions/checkout@v4
- name: Copy env file
run: cp .env.example .env
+ # The code is checked out under uid 1001 - reset this to 1000 for the
+ # container to run tests successfully
- name: Fix permissions
run: sudo chown -R 1000:1000 .
- name: Build the test DB
@@ -99,8 +122,8 @@ jobs:
python_lint:
name: Run Python linter
runs-on: ubuntu-latest
- needs: python_lint_required_check
- if: needs.python_lint_required_check.outputs.any_changed == 'true'
+ needs: python_lint_required
+ if: needs.python_lint_required.outputs.lint_should_run == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
@@ -116,8 +139,8 @@ jobs:
vulture:
name: Find unused code
runs-on: ubuntu-latest
- needs: python_lint_required_check
- if: needs.python_lint_required_check.outputs.any_changed == 'true'
+ needs: python_lint_required
+ if: needs.python_lint_required.outputs.lint_should_run == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
diff --git a/mathesar/tests/api/test_table_api.py b/mathesar/tests/api/test_table_api.py
index 9ff7aafddc..18df6ca1e0 100644
--- a/mathesar/tests/api/test_table_api.py
+++ b/mathesar/tests/api/test_table_api.py
@@ -2083,7 +2083,6 @@ def test_create_table_using_duplicate_id_excel_data_file(client, duplicate_id_ex
def test_create_table_using_null_id_excel_data_file(client, null_id_excel_data_file, schema):
- # silly comment
table_name = 'null_id'
expt_name = get_expected_name(table_name, data_file=null_id_excel_data_file)
first_row = (1, '1.0', 'John', '25')
From 7f4dffa89e556e14658cb898c0feec1065b11169 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 15:05:07 +0800
Subject: [PATCH 103/111] fix workflow syntax error
---
.github/workflows/backend-validation.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/backend-validation.yml b/.github/workflows/backend-validation.yml
index 97f1823e69..0062615a94 100644
--- a/.github/workflows/backend-validation.yml
+++ b/.github/workflows/backend-validation.yml
@@ -99,7 +99,7 @@ jobs:
sql_tests:
name: Run SQL tests
runs-on: ubuntu-latest
- needs: sql_tests_required_check
+ needs: sql_tests_required
if: needs.sql_tests_required.outputs.tests_should_run == 'true'
strategy:
matrix:
From 414654a152a5ea1d660cadd002579cfb7ddfd551 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 15:37:30 +0800
Subject: [PATCH 104/111] Move front end checks to main validation file
---
.github/workflows/backend-validation.yml | 164 ---------
.github/workflows/run-lint-audit-tests-ui.yml | 129 -------
.github/workflows/test-and-lint-code.yml | 332 ++++++++++++++++++
3 files changed, 332 insertions(+), 293 deletions(-)
delete mode 100644 .github/workflows/backend-validation.yml
delete mode 100644 .github/workflows/run-lint-audit-tests-ui.yml
create mode 100644 .github/workflows/test-and-lint-code.yml
diff --git a/.github/workflows/backend-validation.yml b/.github/workflows/backend-validation.yml
deleted file mode 100644
index 0062615a94..0000000000
--- a/.github/workflows/backend-validation.yml
+++ /dev/null
@@ -1,164 +0,0 @@
-# Since we're using both the "require pull request" and "require merge queue"
-# requirements for develop and master branches, there's no reason to run tests
-# on every push. Instead, we're using the recommended "merge_group" formulation
-# that runs status checks and reports them whenever a PR is added to the merge
-# queue.
-
-name: Backend tests and linting
-on: [pull_request, merge_group]
-jobs:
-
-################################################################################
-## FILE CHANGE CHECKERS ##
-## ##
-## These jobs check which files have changed so that we can call appropriate ##
-## testing, auditing, and linting jobs. Jobs in this section should check for ##
-## file changes that would indicate whether we need to run some particular ##
-## test suite, then they should output 'true' if such file changes are found. ##
-## ##
-################################################################################
-
- python_tests_required:
- name: Check for file changes requiring python tests
- runs-on: ubuntu-latest
- outputs:
- tests_should_run: ${{ steps.changed_files.outputs.any_changed }}
- steps:
- - uses: actions/checkout@v4
- - name: Get changed files
- id: changed_files
- uses: tj-actions/changed-files@v39
- with:
- files: |
- *.py
- mathesar/**
- db/**
-
- python_lint_required:
- name: Check for file changes requiring python linter
- runs-on: ubuntu-latest
- outputs:
- lint_should_run: ${{ steps.changed_files.outputs.any_changed }}
- steps:
- - uses: actions/checkout@v4
- - name: Get changed files
- id: changed_files
- uses: tj-actions/changed-files@v39
- with:
- files: '**.py'
-
- sql_tests_required:
- name: Check for file changes requiring SQL tests
- runs-on: ubuntu-latest
- outputs:
- tests_should_run: ${{ steps.changed_files.outputs.any_changed }}
- steps:
- - uses: actions/checkout@v4
- - name: Get changed files
- id: changed_files
- uses: tj-actions/changed-files@v39
- with:
- files: '**.sql'
-
-################################################################################
-## TEST/LINT RUNNERS ##
-## ##
-## These jobs run tests and linters. Each job in this section should be ##
-## dependent on one of the FILE CHANGE CHECKERS above, and should only run if ##
-## appropriate files have changed. You can see this by using a `needs:` block ##
-## to make the job dependent on the relevant file checker, and an `if:` block ##
-## to ensure that the file checker returned 'true' before running the actual ##
-## job. Job IDs in this section must be namespaced (so `python_tests` ##
-## instead of just `tests`). ##
-## ##
-################################################################################
-
- python_tests:
- name: Run Python tests
- runs-on: ubuntu-latest
- needs: python_tests_required
- if: needs.python_tests_required.outputs.tests_should_run == 'true'
- strategy:
- matrix:
- pg-version: [13, 14, 15]
- steps:
- - uses: actions/checkout@v4
- - name: Copy env file
- run: cp .env.example .env
- # The code is checked out under uid 1001 - reset this to 1000 for the
- # container to run tests successfully
- - name: Fix permissions
- run: sudo chown -R 1000:1000 .
- - name: Build the stack
- run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d test-service
- env:
- PG_VERSION: ${{ matrix.pg-version }}
- - name: Run tests with pytest
- run: docker exec mathesar_service_test ./run_pytest.sh
-
- sql_tests:
- name: Run SQL tests
- runs-on: ubuntu-latest
- needs: sql_tests_required
- if: needs.sql_tests_required.outputs.tests_should_run == 'true'
- strategy:
- matrix:
- pg-version: [13, 14, 15]
- steps:
- - uses: actions/checkout@v4
- - name: Copy env file
- run: cp .env.example .env
- # The code is checked out under uid 1001 - reset this to 1000 for the
- # container to run tests successfully
- - name: Fix permissions
- run: sudo chown -R 1000:1000 .
- - name: Build the test DB
- run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d dev-db
- env:
- PG_VERSION: ${{ matrix.pg-version }}
- - name: Run tests with pg_prove
- run: docker exec mathesar_dev_db /bin/bash /sql/run_tests.sh
-
- python_lint:
- name: Run Python linter
- runs-on: ubuntu-latest
- needs: python_lint_required
- if: needs.python_lint_required.outputs.lint_should_run == 'true'
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v4
- - name: Run flake8
- uses: julianwachholz/flake8-action@main
- with:
- checkName: "flake8"
- path: "."
- plugins: flake8-no-types
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- vulture:
- name: Find unused code
- runs-on: ubuntu-latest
- needs: python_lint_required
- if: needs.python_lint_required.outputs.lint_should_run == 'true'
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v4
- - name: Install Vulture
- run: pip3 install vulture
- - name: Run Vulture
- run: vulture .
-
- tests:
- runs-on: ubuntu-latest
- needs: [python_tests, sql_tests]
- steps:
- - name: Report success
- run: echo "Backend tests succeeded or skipped!"
-
- lint:
- runs-on: ubuntu-latest
- needs: python_lint
- steps:
- - name: Report success
- run: echo "Python linter succeeded or skipped!"
diff --git a/.github/workflows/run-lint-audit-tests-ui.yml b/.github/workflows/run-lint-audit-tests-ui.yml
deleted file mode 100644
index 3e9aa41f06..0000000000
--- a/.github/workflows/run-lint-audit-tests-ui.yml
+++ /dev/null
@@ -1,129 +0,0 @@
-name: UI - Lint, Audit and Tests
-
-on:
- push:
- paths:
- - 'mathesar_ui/**'
- pull_request:
- paths:
- - 'mathesar_ui/**'
-
-jobs:
- format:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ./mathesar_ui
- timeout-minutes: 5
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-node@v2
- with:
- node-version: 18
- - id: npm-cache-dir
- run: echo "::set-output name=dir::$(npm config get cache)"
- - uses: actions/cache@v2
- id: npm-cache
- with:
- path: ${{ steps.npm-cache-dir.outputs.dir }}
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: ${{ runner.os }}-node-
- - run: npm ci --no-audit --prefer-offline
- - run: npm run check-format
-
- lint:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ./mathesar_ui
- timeout-minutes: 5
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-node@v2
- with:
- node-version: 18
- - id: npm-cache-dir
- run: echo "::set-output name=dir::$(npm config get cache)"
- - uses: actions/cache@v2
- id: npm-cache
- with:
- path: ${{ steps.npm-cache-dir.outputs.dir }}
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: ${{ runner.os }}-node-
- - run: npm ci --no-audit --prefer-offline
- - run: npm run lint
-
- typecheck:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ./mathesar_ui
- timeout-minutes: 5
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-node@v2
- with:
- node-version: 18
- - id: npm-cache-dir
- run: echo "::set-output name=dir::$(npm config get cache)"
- - uses: actions/cache@v2
- id: npm-cache
- with:
- path: ${{ steps.npm-cache-dir.outputs.dir }}
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: ${{ runner.os }}-node-
- - run: npm ci --no-audit --prefer-offline
- - run: npm run typecheck
-
- audit:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ./mathesar_ui
- timeout-minutes: 5
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-node@v2
- with:
- node-version: 18
- - id: npm-cache-dir
- run: echo "::set-output name=dir::$(npm config get cache)"
- - uses: actions/cache@v2
- id: npm-cache
- with:
- path: ${{ steps.npm-cache-dir.outputs.dir }}
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: ${{ runner.os }}-node-
- - run: npm ci
- - uses: oke-py/npm-audit-action@v1.8.2
- with:
- audit_level: moderate
- github_token: ${{ secrets.GITHUB_TOKEN }}
- create_pr_comments: false
- dedupe_issues: true
- working_directory: './mathesar_ui'
- issue_labels: 'restricted: maintainers,type: bug,work: frontend,status: triage'
- production_flag: true
- continue-on-error: true
-
- tests:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ./mathesar_ui
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-node@v2
- with:
- node-version: 18
- - id: npm-cache-dir
- run: echo "::set-output name=dir::$(npm config get cache)"
- - uses: actions/cache@v2
- id: npm-cache
- with:
- path: ${{ steps.npm-cache-dir.outputs.dir }}
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: ${{ runner.os }}-node-
- - run: npm ci --no-audit --prefer-offline
- - run: npm test
diff --git a/.github/workflows/test-and-lint-code.yml b/.github/workflows/test-and-lint-code.yml
new file mode 100644
index 0000000000..c52cd13c61
--- /dev/null
+++ b/.github/workflows/test-and-lint-code.yml
@@ -0,0 +1,332 @@
+## This workflow runs all tests, audits, and linters for Mathesar's source code.
+## It's set up to run for every pull request change, as well as when a pull
+## request is added to the merge queue. This, combined with our branch
+## protections requiring pull requests and a merge queue for `develop` and
+## `master` ensures that no code is merged into those branches without
+## appropriate tests having run.
+
+name: Test and Lint Code
+on: [pull_request, merge_group]
+jobs:
+
+################################################################################
+## FILE CHANGE CHECKERS ##
+## ##
+## These jobs check which files have changed so that we can call appropriate ##
+## testing, auditing, and linting jobs. Jobs in this section should check for ##
+## file changes that would indicate whether we need to run some particular ##
+## test suite, then they should output 'true' if such file changes are found. ##
+## ##
+################################################################################
+
+ python_tests_required:
+ name: Check for file changes requiring python tests
+ runs-on: ubuntu-latest
+ outputs:
+ tests_should_run: ${{ steps.changed_files.outputs.any_changed }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Get changed files
+ id: changed_files
+ uses: tj-actions/changed-files@v39
+ with:
+ files: |
+ *.py
+ mathesar/**
+ db/**
+
+ python_lint_required:
+ name: Check for file changes requiring python linter
+ runs-on: ubuntu-latest
+ outputs:
+ lint_should_run: ${{ steps.changed_files.outputs.any_changed }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Get changed files
+ id: changed_files
+ uses: tj-actions/changed-files@v39
+ with:
+ files: '**.py'
+
+ sql_tests_required:
+ name: Check for file changes requiring SQL tests
+ runs-on: ubuntu-latest
+ outputs:
+ tests_should_run: ${{ steps.changed_files.outputs.any_changed }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Get changed files
+ id: changed_files
+ uses: tj-actions/changed-files@v39
+ with:
+ files: '**.sql'
+
+ front_end_checks_required:
+ name: Check for file changes requiring front end checks
+ runs-on: ubuntu-latest
+ outputs:
+ checks_should_run: ${{ steps.changed_files.outputs.any_changed }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Get changed files
+ id: changed_files
+ uses: tj-actions/changed-files@v39
+ with:
+ files: 'mathesar_ui/**'
+
+################################################################################
+## BACK END TEST/LINT RUNNERS ##
+## ##
+## These jobs run tests and linters. Each job in this section should be ##
+## dependent on one of the FILE CHANGE CHECKERS above, and should only run if ##
+## appropriate files have changed. You can see this by using a `needs:` block ##
+## to make the job dependent on the relevant file checker, and an `if:` block ##
+## to ensure that the file checker returned 'true' before running the actual ##
+## job. Job IDs in this section must be namespaced (so `python_tests` ##
+## instead of just `tests`). ##
+## ##
+################################################################################
+
+ python_tests:
+ name: Run Python tests
+ runs-on: ubuntu-latest
+ needs: python_tests_required
+ if: needs.python_tests_required.outputs.tests_should_run == 'true'
+ strategy:
+ matrix:
+ pg-version: [13, 14, 15]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Copy env file
+ run: cp .env.example .env
+ # The code is checked out under uid 1001 - reset this to 1000 for the
+ # container to run tests successfully
+ - name: Fix permissions
+ run: sudo chown -R 1000:1000 .
+ - name: Build the stack
+ run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d test-service
+ env:
+ PG_VERSION: ${{ matrix.pg-version }}
+ - name: Run tests with pytest
+ run: docker exec mathesar_service_test ./run_pytest.sh
+
+ sql_tests:
+ name: Run SQL tests
+ runs-on: ubuntu-latest
+ needs: sql_tests_required
+ if: needs.sql_tests_required.outputs.tests_should_run == 'true'
+ strategy:
+ matrix:
+ pg-version: [13, 14, 15]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Copy env file
+ run: cp .env.example .env
+ # The code is checked out under uid 1001 - reset this to 1000 for the
+ # container to run tests successfully
+ - name: Fix permissions
+ run: sudo chown -R 1000:1000 .
+ - name: Build the test DB
+ run: docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d dev-db
+ env:
+ PG_VERSION: ${{ matrix.pg-version }}
+ - name: Run tests with pg_prove
+ run: docker exec mathesar_dev_db /bin/bash /sql/run_tests.sh
+
+ python_lint:
+ name: Run Python linter
+ runs-on: ubuntu-latest
+ needs: python_lint_required
+ if: needs.python_lint_required.outputs.lint_should_run == 'true'
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v4
+ - name: Run flake8
+ uses: julianwachholz/flake8-action@main
+ with:
+ checkName: "flake8"
+ path: "."
+ plugins: flake8-no-types
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ vulture:
+ name: Find unused code
+ runs-on: ubuntu-latest
+ needs: python_lint_required
+ if: needs.python_lint_required.outputs.lint_should_run == 'true'
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v4
+ - name: Install Vulture
+ run: pip3 install vulture
+ - name: Run Vulture
+ run: vulture .
+
+################################################################################
+## FRONT END CHECK RUNNERS ##
+## ##
+## These jobs run front end checks. Each job in this section should be ##
+## dependent on one of the FILE CHANGE CHECKERS above (currently only ##
+## front_end_checks_required), and should only run if appropriate files have ##
+## changed. You can see this by using a `needs:` block to make the job ##
+## dependent on the relevant file checker, and an `if:` block to ensure that ##
+## the file checker returned 'true' before running the actual job. `lint` and ##
+## `tests` Job IDs in this section must be namespaced (`front_end_tests` ##
+## rather than `tests`). ##
+## ##
+################################################################################
+
+ format:
+ runs-on: ubuntu-latest
+ needs: front_end_checks_required
+ if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
+ defaults:
+ run:
+ working-directory: ./mathesar_ui
+ timeout-minutes: 5
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ - id: npm-cache-dir
+ run: echo "::set-output name=dir::$(npm config get cache)"
+ - uses: actions/cache@v3
+ id: npm-cache
+ with:
+ path: ${{ steps.npm-cache-dir.outputs.dir }}
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: ${{ runner.os }}-node-
+ - run: npm ci --no-audit --prefer-offline
+ - run: npm run check-format
+
+ front_end_lint:
+ name: Run front end linter
+ runs-on: ubuntu-latest
+ needs: front_end_checks_required
+ if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
+ defaults:
+ run:
+ working-directory: ./mathesar_ui
+ timeout-minutes: 5
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ - id: npm-cache-dir
+ run: echo "::set-output name=dir::$(npm config get cache)"
+ - uses: actions/cache@v3
+ id: npm-cache
+ with:
+ path: ${{ steps.npm-cache-dir.outputs.dir }}
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: ${{ runner.os }}-node-
+ - run: npm ci --no-audit --prefer-offline
+ - run: npm run lint
+
+ front_end_typecheck:
+ runs-on: ubuntu-latest
+ needs: front_end_checks_required
+ if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
+ defaults:
+ run:
+ working-directory: ./mathesar_ui
+ timeout-minutes: 5
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ - id: npm-cache-dir
+ run: echo "::set-output name=dir::$(npm config get cache)"
+ - uses: actions/cache@v3
+ id: npm-cache
+ with:
+ path: ${{ steps.npm-cache-dir.outputs.dir }}
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: ${{ runner.os }}-node-
+ - run: npm ci --no-audit --prefer-offline
+ - run: npm run typecheck
+
+ front_end_audit:
+ runs-on: ubuntu-latest
+ needs: front_end_checks_required
+ if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
+ defaults:
+ run:
+ working-directory: ./mathesar_ui
+ timeout-minutes: 5
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ - id: npm-cache-dir
+ run: echo "::set-output name=dir::$(npm config get cache)"
+ - uses: actions/cache@v3
+ id: npm-cache
+ with:
+ path: ${{ steps.npm-cache-dir.outputs.dir }}
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: ${{ runner.os }}-node-
+ - run: npm ci
+ - uses: oke-py/npm-audit-action@v1.8.2
+ with:
+ audit_level: moderate
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ create_pr_comments: false
+ dedupe_issues: true
+ working_directory: './mathesar_ui'
+ issue_labels: 'restricted: maintainers,type: bug,work: frontend,status: triage'
+ production_flag: true
+ continue-on-error: true
+
+ front_end_tests:
+ runs-on: ubuntu-latest
+ needs: front_end_checks_required
+ if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
+ defaults:
+ run:
+ working-directory: ./mathesar_ui
+ timeout-minutes: 15
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ - id: npm-cache-dir
+ run: echo "::set-output name=dir::$(npm config get cache)"
+ - uses: actions/cache@v3
+ id: npm-cache
+ with:
+ path: ${{ steps.npm-cache-dir.outputs.dir }}
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: ${{ runner.os }}-node-
+ - run: npm ci --no-audit --prefer-offline
+ - run: npm test
+
+################################################################################
+## REQUIRED TEST/LINT COLLECTORS ##
+## Jobs in this section collect outputs from various testing and linting jobs ##
+## above, and associate their status with required job IDs for branch ##
+## protection purposes. At the moment, they only need to have each required ##
+## check as a dependency. Required checks should skip themselves if no ##
+## relevant files have changed. ##
+## ##
+################################################################################
+
+ tests:
+ runs-on: ubuntu-latest
+ needs: [python_tests, sql_tests, front_end_tests]
+ steps:
+ - name: Report success
+ run: echo "All tests succeeded or skipped!"
+
+ lint:
+ runs-on: ubuntu-latest
+ needs: [python_lint, front_end_lint]
+ steps:
+ - name: Report success
+ run: echo "All linters succeeded or skipped!"
From e0e8be1528515cc3356f4ed9dc309965ef4580df Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 15:47:26 +0800
Subject: [PATCH 105/111] add small change to check front end running behavior
---
.github/workflows/test-and-lint-code.yml | 2 ++
mathesar_ui/src/api/utils/recordUtils.ts | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/test-and-lint-code.yml b/.github/workflows/test-and-lint-code.yml
index c52cd13c61..b303dd9d0e 100644
--- a/.github/workflows/test-and-lint-code.yml
+++ b/.github/workflows/test-and-lint-code.yml
@@ -251,6 +251,7 @@ jobs:
- run: npm run typecheck
front_end_audit:
+ name: Audit front end code
runs-on: ubuntu-latest
needs: front_end_checks_required
if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
@@ -284,6 +285,7 @@ jobs:
continue-on-error: true
front_end_tests:
+ name: Run front end tests
runs-on: ubuntu-latest
needs: front_end_checks_required
if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
diff --git a/mathesar_ui/src/api/utils/recordUtils.ts b/mathesar_ui/src/api/utils/recordUtils.ts
index 4dbe3db16e..161a60cd4a 100644
--- a/mathesar_ui/src/api/utils/recordUtils.ts
+++ b/mathesar_ui/src/api/utils/recordUtils.ts
@@ -15,7 +15,7 @@ type ColumnErrors = ImmutableMap;
* about which column(s) caused the error, and sometimes we just get a generic
* top-level error message. Because the API schema supports sending multiple
* errors in one response, we use a data structure here that can handle both
- * situations at the same time.
+ * situations at the same time. diff
*/
export interface DetailedRecordsErrors {
columnErrors: ColumnErrors;
From 37fcbb12e1b60e953a2ac3b561393f5a8e0133f6 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 15:53:17 +0800
Subject: [PATCH 106/111] modify FE tests to fail (behavior check)
---
mathesar_ui/src/api/utils/recordUtils.ts | 2 +-
mathesar_ui/src/utils/__tests__/api.test.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/mathesar_ui/src/api/utils/recordUtils.ts b/mathesar_ui/src/api/utils/recordUtils.ts
index 161a60cd4a..4dbe3db16e 100644
--- a/mathesar_ui/src/api/utils/recordUtils.ts
+++ b/mathesar_ui/src/api/utils/recordUtils.ts
@@ -15,7 +15,7 @@ type ColumnErrors = ImmutableMap;
* about which column(s) caused the error, and sometimes we just get a generic
* top-level error message. Because the API schema supports sending multiple
* errors in one response, we use a data structure here that can handle both
- * situations at the same time. diff
+ * situations at the same time.
*/
export interface DetailedRecordsErrors {
columnErrors: ColumnErrors;
diff --git a/mathesar_ui/src/utils/__tests__/api.test.ts b/mathesar_ui/src/utils/__tests__/api.test.ts
index 371998775d..4cdd55af36 100644
--- a/mathesar_ui/src/utils/__tests__/api.test.ts
+++ b/mathesar_ui/src/utils/__tests__/api.test.ts
@@ -14,7 +14,7 @@ test('getMostImportantRequestStatusState', () => {
{ state: 'success' },
{ state: 'failure', errors: ['foo'] },
]),
- ).toBe('failure');
+ ).toBe('failue');
expect(getMostImportantRequestStatusState([{ state: 'success' }])).toBe(
'success',
From 3032705cc3d472b6a8546237d3fb92e512e7bde9 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 16:05:53 +0800
Subject: [PATCH 107/111] reset tests to pass, format to fail
---
mathesar_ui/src/api/users.ts | 6 +++---
mathesar_ui/src/utils/__tests__/api.test.ts | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/mathesar_ui/src/api/users.ts b/mathesar_ui/src/api/users.ts
index ad2599105f..158b4830ca 100644
--- a/mathesar_ui/src/api/users.ts
+++ b/mathesar_ui/src/api/users.ts
@@ -8,13 +8,13 @@ import {
type PaginatedResponse,
} from './utils/requestUtils';
-export interface UnsavedUser {
+export interface UnsavedUser
+{
full_name: string | null;
email: string | null;
username: string;
password: string;
- display_language: Locales;
-}
+ display_language: Locales;}
export type UserRole = 'viewer' | 'editor' | 'manager';
diff --git a/mathesar_ui/src/utils/__tests__/api.test.ts b/mathesar_ui/src/utils/__tests__/api.test.ts
index 4cdd55af36..371998775d 100644
--- a/mathesar_ui/src/utils/__tests__/api.test.ts
+++ b/mathesar_ui/src/utils/__tests__/api.test.ts
@@ -14,7 +14,7 @@ test('getMostImportantRequestStatusState', () => {
{ state: 'success' },
{ state: 'failure', errors: ['foo'] },
]),
- ).toBe('failue');
+ ).toBe('failure');
expect(getMostImportantRequestStatusState([{ state: 'success' }])).toBe(
'success',
From db5cc248f67ff960282c02769671f4194d1ef14f Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 16:25:52 +0800
Subject: [PATCH 108/111] Improve job names and ID clarity
---
.github/workflows/test-and-lint-code.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/test-and-lint-code.yml b/.github/workflows/test-and-lint-code.yml
index b303dd9d0e..cb391426c9 100644
--- a/.github/workflows/test-and-lint-code.yml
+++ b/.github/workflows/test-and-lint-code.yml
@@ -177,7 +177,8 @@ jobs:
## ##
################################################################################
- format:
+ front_end_format:
+ name: Check front end code format
runs-on: ubuntu-latest
needs: front_end_checks_required
if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
@@ -227,6 +228,7 @@ jobs:
- run: npm run lint
front_end_typecheck:
+ name: Check front end types
runs-on: ubuntu-latest
needs: front_end_checks_required
if: needs.front_end_checks_required.outputs.checks_should_run == 'true'
From 5adc78951f47823d6623254e3a3568263771405b Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 16:27:50 +0800
Subject: [PATCH 109/111] Remove unneeded collectors
---
.github/workflows/test-and-lint-code.yml | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/.github/workflows/test-and-lint-code.yml b/.github/workflows/test-and-lint-code.yml
index cb391426c9..928f05492f 100644
--- a/.github/workflows/test-and-lint-code.yml
+++ b/.github/workflows/test-and-lint-code.yml
@@ -310,27 +310,3 @@ jobs:
restore-keys: ${{ runner.os }}-node-
- run: npm ci --no-audit --prefer-offline
- run: npm test
-
-################################################################################
-## REQUIRED TEST/LINT COLLECTORS ##
-## Jobs in this section collect outputs from various testing and linting jobs ##
-## above, and associate their status with required job IDs for branch ##
-## protection purposes. At the moment, they only need to have each required ##
-## check as a dependency. Required checks should skip themselves if no ##
-## relevant files have changed. ##
-## ##
-################################################################################
-
- tests:
- runs-on: ubuntu-latest
- needs: [python_tests, sql_tests, front_end_tests]
- steps:
- - name: Report success
- run: echo "All tests succeeded or skipped!"
-
- lint:
- runs-on: ubuntu-latest
- needs: [python_lint, front_end_lint]
- steps:
- - name: Report success
- run: echo "All linters succeeded or skipped!"
From 9c4d02b89e06a2ca07a79eaa1e3b5e32379446f3 Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 16:38:16 +0800
Subject: [PATCH 110/111] restore collector for matrix-strategy tests
---
.github/workflows/test-and-lint-code.yml | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/.github/workflows/test-and-lint-code.yml b/.github/workflows/test-and-lint-code.yml
index 928f05492f..b59fbe713c 100644
--- a/.github/workflows/test-and-lint-code.yml
+++ b/.github/workflows/test-and-lint-code.yml
@@ -310,3 +310,20 @@ jobs:
restore-keys: ${{ runner.os }}-node-
- run: npm ci --no-audit --prefer-offline
- run: npm test
+
+################################################################################
+## REQUIRED TEST/LINT COLLECTORS ##
+## Jobs in this section collect outputs from matrix-strategy testing jobs, ##
+## since these are otherwise impossible to capture for branch protection ##
+## purposes. At the moment, they only need to have each required check as a ##
+## dependency. Required checks should skip themselves if no relevant files ##
+## have changed. ##
+## ##
+################################################################################
+
+ matrix_tests:
+ runs-on: ubuntu-latest
+ needs: [python_tests, sql_tests]
+ steps:
+ - name: Report success
+ run: echo "All tests succeeded or skipped!"
From 707dcc388afb88d7b05ebffa50d576cbd109906f Mon Sep 17 00:00:00 2001
From: Brent Moran
Date: Thu, 26 Oct 2023 16:42:31 +0800
Subject: [PATCH 111/111] restore front end formatting (should pass)
---
mathesar_ui/src/api/users.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mathesar_ui/src/api/users.ts b/mathesar_ui/src/api/users.ts
index 158b4830ca..ad2599105f 100644
--- a/mathesar_ui/src/api/users.ts
+++ b/mathesar_ui/src/api/users.ts
@@ -8,13 +8,13 @@ import {
type PaginatedResponse,
} from './utils/requestUtils';
-export interface UnsavedUser
-{
+export interface UnsavedUser {
full_name: string | null;
email: string | null;
username: string;
password: string;
- display_language: Locales;}
+ display_language: Locales;
+}
export type UserRole = 'viewer' | 'editor' | 'manager';