Skip to content

Commit 93eff78

Browse files
committed
Make custom type and foreign key mutually exclusive
In the create table dialog a column can now have either a custom display type or a foreign key target, but not both - a foreign key column's type is determined by the referenced primary key, so a custom type doesn't apply. Setting one clears and disables the other, and the foreign key select stays disabled on the primary key column and when no targets exist. Also add "Controls how Datasette displays and edits this column" help text (with aria-describedby) under the custom type selector in both the create and alter dialogs, and style the alter dialog help text.
1 parent 065e779 commit 93eff78

2 files changed

Lines changed: 73 additions & 1 deletion

File tree

datasette/static/app.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1953,7 +1953,8 @@ dialog.table-create-dialog::backdrop {
19531953
font-size: 0.72rem;
19541954
}
19551955

1956-
.table-create-detail-help {
1956+
.table-create-detail-help,
1957+
.table-alter-detail-help {
19571958
color: var(--muted);
19581959
font-size: 0.82rem;
19591960
line-height: 1.35;

datasette/static/edit-tools.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,11 +422,42 @@ function syncTableCreateForeignKeyOptions(row, state) {
422422
);
423423
}
424424

425+
function syncTableCreateCustomTypeAndForeignKey(row, state, isFirstColumn) {
426+
var customTypeSelect = row.querySelector(".table-create-custom-column-type");
427+
var foreignKeySelect = row.querySelector(".table-create-foreign-key-target");
428+
if (!foreignKeySelect) {
429+
return;
430+
}
431+
432+
var hasCustomType = customTypeSelect && !!customTypeSelect.value;
433+
var hasForeignKey = !!foreignKeySelect.value;
434+
435+
if (customTypeSelect && hasForeignKey) {
436+
customTypeSelect.value = "";
437+
updateTableCreateCustomColumnTypePlaceholder(customTypeSelect);
438+
hasCustomType = false;
439+
}
440+
441+
if (isFirstColumn || hasCustomType) {
442+
foreignKeySelect.value = "";
443+
foreignKeySelect.dataset.selectedKey = "";
444+
updateTableCreateCustomColumnTypePlaceholder(foreignKeySelect);
445+
hasForeignKey = false;
446+
}
447+
448+
if (customTypeSelect) {
449+
customTypeSelect.disabled = state.isSaving;
450+
}
451+
foreignKeySelect.disabled =
452+
state.isSaving || isFirstColumn || foreignKeySelect.options.length <= 1;
453+
}
454+
425455
function refreshTableCreateForeignKeyControls(state) {
426456
tableCreateDialogRows(state).forEach(function (row, index) {
427457
if (index > 0) {
428458
syncTableCreateForeignKeyOptions(row, state);
429459
}
460+
syncTableCreateCustomTypeAndForeignKey(row, state, index === 0);
430461
});
431462
}
432463

@@ -455,6 +486,7 @@ function updateTableCreateColumnRules(state) {
455486
} else {
456487
syncTableCreateForeignKeyOptions(row, state);
457488
}
489+
syncTableCreateCustomTypeAndForeignKey(row, state, isFirstColumn);
458490
}
459491
});
460492
updateTableCreateMoveButtons(state);
@@ -639,11 +671,19 @@ function createTableColumnRow(state, column) {
639671
customTypeLabel.className = "table-create-detail-label";
640672
customTypeLabel.setAttribute("for", customTypeId);
641673
customTypeLabel.textContent = "Custom type";
674+
var customTypeHelpId = "table-create-column-custom-type-help-" + index;
675+
var customTypeHelp = document.createElement("p");
676+
customTypeHelp.id = customTypeHelpId;
677+
customTypeHelp.className = "table-create-detail-help";
678+
customTypeHelp.textContent =
679+
"Controls how Datasette displays and edits this column";
642680
customTypeSelect = createTableCustomColumnTypeSelect();
643681
customTypeSelect.id = customTypeId;
682+
customTypeSelect.setAttribute("aria-describedby", customTypeHelpId);
644683
customTypeSelect.value = column && column.customType ? column.customType : "";
645684
updateTableCreateCustomColumnTypePlaceholder(customTypeSelect);
646685
customTypeField.appendChild(customTypeLabel);
686+
customTypeField.appendChild(customTypeHelp);
647687
customTypeField.appendChild(customTypeSelect);
648688
}
649689

@@ -733,11 +773,20 @@ function createTableColumnRow(state, column) {
733773
clearTableCreateDialogError(state);
734774
syncTableCreateCustomTypeForSqliteType(row);
735775
syncTableCreateForeignKeyOptions(row, state);
776+
syncTableCreateCustomTypeAndForeignKey(
777+
row,
778+
state,
779+
row === state.columnList.firstElementChild,
780+
);
736781
});
737782
if (customTypeSelect) {
738783
customTypeSelect.addEventListener("change", function () {
739784
clearTableCreateDialogError(state);
740785
updateTableCreateCustomColumnTypePlaceholder(customTypeSelect);
786+
if (customTypeSelect.value) {
787+
foreignKeySelect.value = "";
788+
foreignKeySelect.dataset.selectedKey = "";
789+
}
741790
var option = tableCreateCustomColumnType(customTypeSelect.value);
742791
if (
743792
option &&
@@ -747,6 +796,11 @@ function createTableColumnRow(state, column) {
747796
typeSelect.value = option.fixedSqliteType;
748797
syncTableCreateForeignKeyOptions(row, state);
749798
}
799+
syncTableCreateCustomTypeAndForeignKey(
800+
row,
801+
state,
802+
row === state.columnList.firstElementChild,
803+
);
750804
});
751805
}
752806
pkInput.addEventListener("change", function () {
@@ -757,6 +811,15 @@ function createTableColumnRow(state, column) {
757811
foreignKeySelect.dataset.selectedKey = foreignKeySelect.value;
758812
clearTableCreateDialogError(state);
759813
updateTableCreateCustomColumnTypePlaceholder(foreignKeySelect);
814+
if (customTypeSelect && foreignKeySelect.value) {
815+
customTypeSelect.value = "";
816+
updateTableCreateCustomColumnTypePlaceholder(customTypeSelect);
817+
}
818+
syncTableCreateCustomTypeAndForeignKey(
819+
row,
820+
state,
821+
row === state.columnList.firstElementChild,
822+
);
760823
});
761824

762825
expandButton.addEventListener("click", function () {
@@ -1664,11 +1727,19 @@ function createTableAlterColumnRow(state, column) {
16641727
customTypeLabel.className = "table-alter-detail-label";
16651728
customTypeLabel.setAttribute("for", customTypeId);
16661729
customTypeLabel.textContent = "Custom type";
1730+
var customTypeHelpId = "table-alter-column-custom-type-help-" + index;
1731+
var customTypeHelp = document.createElement("p");
1732+
customTypeHelp.id = customTypeHelpId;
1733+
customTypeHelp.className = "table-alter-detail-help";
1734+
customTypeHelp.textContent =
1735+
"Controls how Datasette displays and edits this column";
16671736
customTypeSelect = createTableAlterCustomColumnTypeSelect();
16681737
customTypeSelect.id = customTypeId;
1738+
customTypeSelect.setAttribute("aria-describedby", customTypeHelpId);
16691739
customTypeSelect.value = originalCustomType;
16701740
updateTableAlterCustomColumnTypePlaceholder(customTypeSelect);
16711741
customTypeField.appendChild(customTypeLabel);
1742+
customTypeField.appendChild(customTypeHelp);
16721743
customTypeField.appendChild(customTypeSelect);
16731744
}
16741745

0 commit comments

Comments
 (0)