Merge remote-tracking branch 'origin/main' into feature/kanban_board

This commit is contained in:
Elian Doran
2025-07-21 18:24:36 +03:00
20 changed files with 859 additions and 674 deletions

View File

@@ -296,6 +296,7 @@ interface AttributeDetailOpts {
y: number;
focus?: "name";
parent?: HTMLElement;
hideMultiplicity?: boolean;
}
interface SearchRelatedResponse {
@@ -478,7 +479,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
});
}
async showAttributeDetail({ allAttributes, attribute, isOwned, x, y, focus }: AttributeDetailOpts) {
async showAttributeDetail({ allAttributes, attribute, isOwned, x, y, focus, hideMultiplicity }: AttributeDetailOpts) {
if (!attribute) {
this.hide();
@@ -529,7 +530,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
this.$rowPromotedAlias.toggle(!!definition.isPromoted);
this.$inputPromotedAlias.val(definition.promotedAlias || "").attr("disabled", disabledFn);
this.$rowMultiplicity.toggle(["label-definition", "relation-definition"].includes(this.attrType || ""));
this.$rowMultiplicity.toggle(["label-definition", "relation-definition"].includes(this.attrType || "") && !hideMultiplicity);
this.$inputMultiplicity.val(definition.multiplicity || "").attr("disabled", disabledFn);
this.$rowLabelType.toggle(this.attrType === "label-definition");

View File

@@ -66,7 +66,8 @@ export default class TableColumnEditing extends Component {
isOwned: true,
x: 0,
y: 150,
focus: "name"
focus: "name",
hideMultiplicity: true
});
}

View File

@@ -30,6 +30,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
const sorters = tabulator.getSorters();
const sorter = sorters.find(sorter => sorter.field === field);
const isUserDefinedColumn = (!!field && (field?.startsWith("labels.") || field?.startsWith("relations.")));
contextMenu.show({
items: [
@@ -65,7 +66,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
{
title: t("table_view.sort-column-clear"),
enabled: sorters.length > 0,
uiIcon: "bx bx-empty",
uiIcon: "bx bx-x-circle",
handler: () => tabulator.clearSort()
},
{
@@ -78,7 +79,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
},
{
title: t("table_view.show-hide-columns"),
uiIcon: "bx bx-empty",
uiIcon: "bx bx-columns",
items: buildColumnItems(tabulator)
},
{ title: "----" },
@@ -103,8 +104,8 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
{ title: "----" },
{
title: t("table_view.edit-column"),
uiIcon: "bx bx-edit",
enabled: !!column.getField() && column.getField() !== "title",
uiIcon: "bx bxs-edit-alt",
enabled: isUserDefinedColumn,
handler: () => getParentComponent(e)?.triggerCommand("addNewTableColumn", {
referenceColumn: column,
columnToEdit: column
@@ -113,7 +114,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
{
title: t("table_view.delete-column"),
uiIcon: "bx bx-trash",
enabled: !!column.getField() && column.getField() !== "title",
enabled: isUserDefinedColumn,
handler: () => getParentComponent(e)?.triggerCommand("deleteTableColumn", {
columnToDelete: column
})
@@ -136,7 +137,7 @@ function showHeaderContextMenu(_e: Event, tabulator: Tabulator) {
items: [
{
title: t("table_view.show-hide-columns"),
uiIcon: "bx bx-empty",
uiIcon: "bx bx-columns",
items: buildColumnItems(tabulator)
},
{ title: "----" },
@@ -173,7 +174,7 @@ export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: F
{ title: "----" },
{
title: t("table_view.row-insert-above"),
uiIcon: "bx bx-list-plus",
uiIcon: "bx bx-horizontal-left bx-rotate-90",
handler: () => getParentComponent(e)?.triggerCommand("addNewRow", {
parentNotePath: parentNoteId,
customOpts: {
@@ -184,7 +185,7 @@ export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: F
},
{
title: t("table_view.row-insert-child"),
uiIcon: "bx bx-empty",
uiIcon: "bx bx-subdirectory-right",
handler: async () => {
const branchId = row.getData().branchId;
const note = await froca.getBranch(branchId)?.getNote();
@@ -199,7 +200,7 @@ export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: F
},
{
title: t("table_view.row-insert-below"),
uiIcon: "bx bx-empty",
uiIcon: "bx bx-horizontal-left bx-rotate-270",
handler: () => getParentComponent(e)?.triggerCommand("addNewRow", {
parentNotePath: parentNoteId,
customOpts: {

View File

@@ -11,12 +11,12 @@ export default function buildFooter(parentNote: FNote) {
}
return /*html*/`\
<button class="btn btn-sm" style="padding: 0px 10px 0px 10px;" data-trigger-command="addNewRow">
<button class="btn btn-sm" data-trigger-command="addNewRow">
<span class="bx bx-plus"></span> ${t("table_view.new-row")}
</button>
<button class="btn btn-sm" style="padding: 0px 10px 0px 10px;" data-trigger-command="addNewTableColumn">
<span class="bx bx-columns"></span> ${t("table_view.new-column")}
<button class="btn btn-sm" data-trigger-command="addNewTableColumn">
<span class="bx bx-carousel"></span> ${t("table_view.new-column")}
</button>
`.trimStart();
}

View File

@@ -20,9 +20,7 @@ export function NoteFormatter(cell: CellComponent, _formatterParams, onRendered)
const iconClass = note.getIcon();
const title = note.title;
const { $noteRef } = buildNoteLink(noteId);
$noteRef.text(title);
$noteRef.prepend($("<span>").addClass(iconClass));
const { $noteRef } = buildNoteLink(noteId, title, iconClass, note.getColorClass());
return $noteRef[0];
}
@@ -53,15 +51,12 @@ export function NoteFormatter(cell: CellComponent, _formatterParams, onRendered)
* Custom formatter for the note title that is quite similar to {@link NoteFormatter}, but where the title and icons are read from separate fields.
*/
export function NoteTitleFormatter(cell: CellComponent) {
const { noteId, iconClass } = cell.getRow().getData();
const { noteId, iconClass, colorClass } = cell.getRow().getData();
if (!noteId) {
return "";
}
const { $noteRef } = buildNoteLink(noteId);
$noteRef.text(cell.getValue());
$noteRef.prepend($("<span>").addClass(iconClass));
const { $noteRef } = buildNoteLink(noteId, cell.getValue(), iconClass, colorClass);
return $noteRef[0].outerHTML;
}
@@ -80,10 +75,15 @@ export function MonospaceFormatter(cell: CellComponent) {
return `<code>${cell.getValue()}</code>`;
}
function buildNoteLink(noteId: string) {
function buildNoteLink(noteId: string, title: string, iconClass: string, colorClass?: string) {
const $noteRef = $("<span>");
const href = `#root/${noteId}`;
$noteRef.addClass("reference-link");
$noteRef.attr("data-href", href);
$noteRef.text(title);
$noteRef.prepend($("<span>").addClass(iconClass));
if (colorClass) {
$noteRef.addClass(colorClass);
}
return { $noteRef, href };
}

View File

@@ -9,6 +9,7 @@ export type TableData = {
labels: Record<string, boolean | string | null>;
relations: Record<string, boolean | string | null>;
branchId: string;
colorClass: string | undefined;
_children?: TableData[];
};
@@ -41,6 +42,7 @@ export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDef
labels,
relations,
branchId: branch.branchId,
colorClass: note.getColorClass()
}
if (note.hasChildren() && (maxDepth < 0 || currentDepth < maxDepth)) {