Skip to content

Commit

Permalink
Merge pull request #945 from trey-wallis/dev
Browse files Browse the repository at this point in the history
* #937 Mulit-Tag sorting feature (#944)

* #937 Mulit-Tag sorting feature

+ Added new Column property - contentsSortDir, it stores information about sorting the content in the cells of the column. At the moment the only type that can store several items in a cell is MultiTag, so the processing logic was added only for it.
+ Added a options submenu for columns with MultiTag type, where you can select the sorting type for the cell contents.

* Renamed `contentsSortDir` to `multiTagSortDir` and `Contents sorting` to `Sort`

* feat: add display name for sort direction

* fix: don't close menu on sort select

* build: fix build errors

* chore: bump to 8.16.0

---------

Co-authored-by: Maxim <45532431+42ama@users.noreply.github.com>
  • Loading branch information
decaf-dev and 42ama committed Apr 28, 2024
2 parents c31d679 + c32320f commit 919ae14
Show file tree
Hide file tree
Showing 21 changed files with 626 additions and 16 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"fundingUrl": {
"Buymeacoffee": "https://www.buymeacoffee.com/treywallis"
},
"version": "8.15.12"
"version": "8.16.0"
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "obsidian-dataloom",
"version": "8.15.12",
"version": "8.16.0",
"description": "Weave together data from diverse sources into different views. Inspired by Excel Spreadsheets and Notion.so.",
"main": "main.js",
"scripts": {
Expand Down
14 changes: 13 additions & 1 deletion src/data/serialize-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
LoomState18,
LoomState19,
LoomState20,
LoomState21,
} from "src/shared/loom-state/types";

import {
Expand All @@ -50,10 +51,11 @@ import {
MigrateState18,
MigrateState19,
MigrateState20,
MigrateState21,
MigrateState22,
} from "src/shared/loom-state/migrate";
import { LoomStateObject } from "src/shared/loom-state/validate-state";
import DeserializationError from "./deserialization-error";
import MigrateState21 from "src/shared/loom-state/migrate/migrate-state-21";

export const serializeState = (state: LoomState): string => {
//Filter out any source rows, as these are populated by the plugin
Expand Down Expand Up @@ -316,6 +318,16 @@ export const deserializeState = (
failedMigration = null;
}

const VERSION_8_16_0 = "8.16.0";
if (isVersionLessThan(fileVersion, VERSION_8_16_0)) {
failedMigration = VERSION_8_16_0;
const nextState = new MigrateState22().migrate(
currentState as LoomState21
);
currentState = nextState;
failedMigration = null;
}

//TODO handle previous versions?
LoomStateObject.check(currentState);

Expand Down
8 changes: 6 additions & 2 deletions src/react/loom-app/body-cell-container/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ import { getFileCellContent } from "src/shared/cell-content/file-cell-content";
import { getDateCellContent } from "src/shared/cell-content/date-cell-content";
import DisabledCell from "../disabled-cell";

import { sortByText } from "src/shared/sort-utils";

interface BaseCellProps {
frontmatterKey: string | null;
aspectRatio: AspectRatio;
Expand Down Expand Up @@ -440,9 +442,11 @@ export default function BodyCellContainer(props: Props) {
}
};
} else {
const { tagIds } = props as MultiTagCellProps;
cellTags = columnTags.filter((tag) => tagIds.includes(tag.id));
const { tagIds, multiTagSortDir } = props as MultiTagCellProps;

cellTags = columnTags.filter((tag) => tagIds.includes(tag.id));
cellTags.sort((a, b) => sortByText(a.content, b.content, multiTagSortDir, false));

handleMenuTriggerBackspaceDown = () => {
onTagCellMultipleRemove(id, tagIds);
};
Expand Down
3 changes: 2 additions & 1 deletion src/react/loom-app/header-menu/base-submenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export default function BaseSubmenu({
columnType === CellType.EMBED ||
columnType === CellType.NUMBER ||
columnType === CellType.LAST_EDITED_TIME ||
columnType === CellType.CREATION_TIME;
columnType === CellType.CREATION_TIME||
columnType === CellType.MULTI_TAG;

return (
<Stack spacing="sm">
Expand Down
16 changes: 16 additions & 0 deletions src/react/loom-app/header-menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import FrontmatterKeySubmenu from "./frontmatter-key-submenu";
import BaseSubmenu from "./base-submenu";
import DateFormatSeparatorSubmenu from "./date-format-separator-submenu";
import TimeFormatSubmenu from "./time-format-submenu";
import MultiTagSortDirSubmenu from "./multitag-sort-dir-submenu";

import {
AspectRatio,
Expand Down Expand Up @@ -88,6 +89,7 @@ export default function HeaderMenu({
numberSeparator,
numberSuffix,
frontmatterKey,
multiTagSortDir,
} = column;
const [submenu, setSubmenu] = React.useState<SubmenuType | null>(null);
const [localValue, setLocalValue] = React.useState(content);
Expand Down Expand Up @@ -241,6 +243,11 @@ export default function HeaderMenu({
onClose();
}

function handleMultiTagSortDirClick(value: SortDir) {
onColumnChange(columnId, { multiTagSortDir: value });
setSubmenu(SubmenuType.OPTIONS);
}

return (
<Menu isOpen={isOpen} id={id} position={position} width={190}>
<div className="dataloom-header-menu">
Expand Down Expand Up @@ -280,6 +287,7 @@ export default function HeaderMenu({
numberPrefix={numberPrefix}
numberSuffix={numberSuffix}
numberSeparator={numberSeparator}
multiTagSortDir={multiTagSortDir}
onBackClick={() => setSubmenu(null)}
onSubmenuChange={setSubmenu}
/>
Expand Down Expand Up @@ -390,6 +398,14 @@ export default function HeaderMenu({
onBackClick={() => setSubmenu(null)}
/>
)}
{submenu === SubmenuType.CONTENTS_SORT_DIR && (
<MultiTagSortDirSubmenu
title="Sort"
value={multiTagSortDir}
onValueClick={handleMultiTagSortDirClick}
onBackClick={() => setSubmenu(null)}
/>
)}
</div>
</Menu>
);
Expand Down
40 changes: 40 additions & 0 deletions src/react/loom-app/header-menu/multitag-sort-dir-submenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import MenuItem from "src/react/shared/menu-item";
import Submenu from "../../shared/submenu";
import { SortDir } from "src/shared/loom-state/types/loom-state";

interface Props {
title: string;
value: SortDir;
onValueClick: (value: SortDir) => void;
onBackClick: () => void;
}

export default function MultiTagSortDirSubmenu({
title,
value,
onValueClick,
onBackClick,
}: Props) {
return (
<Submenu title={title} onBackClick={onBackClick}>
<MenuItem
key={SortDir.ASC}
name="Ascending"
onClick={() => onValueClick(SortDir.ASC)}
isSelected={value === SortDir.ASC}
/>
<MenuItem
key={SortDir.DESC}
name="Descending"
onClick={() => onValueClick(SortDir.DESC)}
isSelected={value === SortDir.DESC}
/>
<MenuItem
key={SortDir.NONE}
name="Default"
onClick={() => onValueClick(SortDir.NONE)}
isSelected={value === SortDir.NONE}
/>
</Submenu>
);
}
13 changes: 13 additions & 0 deletions src/react/loom-app/header-menu/option-submenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DateFormatSeparator,
NumberFormat,
PaddingSize,
SortDir,
} from "src/shared/loom-state/types/loom-state";
import Stack from "src/react/shared/stack";
import Padding from "src/react/shared/padding";
Expand All @@ -17,6 +18,7 @@ import {
getDisplayNameForCurrencyType,
getDisplayNameForDateFormat,
getDisplayNameForDateFormatSeparator,
getDisplayNameForSortDir,
} from "src/shared/loom-state/type-display-names";

interface Props {
Expand All @@ -33,6 +35,7 @@ interface Props {
verticalPadding: PaddingSize;
horizontalPadding: PaddingSize;
aspectRatio: AspectRatio;
multiTagSortDir: SortDir;
onBackClick: () => void;
onSubmenuChange: (value: SubmenuType) => void;
}
Expand All @@ -51,6 +54,7 @@ export default function OptionSubmenu({
horizontalPadding,
title,
dateFormat,
multiTagSortDir,
onBackClick,
onSubmenuChange,
}: Props) {
Expand Down Expand Up @@ -165,6 +169,15 @@ export default function OptionSubmenu({
/>
</>
)}
{type === CellType.MULTI_TAG && (
<MenuItem
name="Sort"
value={getDisplayNameForSortDir(multiTagSortDir)}
onClick={() =>
onSubmenuChange(SubmenuType.CONTENTS_SORT_DIR)
}
/>
)}
</Stack>
</Padding>
</Submenu>
Expand Down
1 change: 1 addition & 0 deletions src/react/loom-app/header-menu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export enum SubmenuType {
TEXT_INPUT_NUMBER_SUFFIX,
TEXT_INPUT_NUMBER_SEPARATOR,
FRONTMATTER_KEY,
CONTENTS_SORT_DIR
}
2 changes: 2 additions & 0 deletions src/react/loom-app/table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ const Table = React.forwardRef<VirtuosoHandle, Props>(function Table(
horizontalPadding,
aspectRatio,
frontmatterKey,
multiTagSortDir
} = column;

const cell = row.cells.find(
Expand Down Expand Up @@ -457,6 +458,7 @@ const Table = React.forwardRef<VirtuosoHandle, Props>(function Table(
{...commonProps}
type={type}
tagIds={tagIds}
multiTagSortDir={multiTagSortDir}
onCellChange={onCellChange}
onTagAdd={onTagAdd}
onTagCellAdd={onTagCellAdd}
Expand Down
2 changes: 2 additions & 0 deletions src/shared/frontmatter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export const deserializeFrontmatterForCell = (
return {
newCell: createMultiTagCell(id, {
hasValidFrontmatter: false,
multiTagSortDir: column.multiTagSortDir
}),
};
}
Expand All @@ -238,6 +239,7 @@ export const deserializeFrontmatterForCell = (
const newCell = createMultiTagCell(id, {
tagIds: cellTagIds,
hasValidFrontmatter: true,
multiTagSortDir: column.multiTagSortDir
});
const nextTags = [...column.tags, ...newTags];
return {
Expand Down
5 changes: 4 additions & 1 deletion src/shared/loom-state/loom-state-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export const createColumn = (options?: {
horizontalPadding: PaddingSize.UNSET,
verticalPadding: PaddingSize.UNSET,
frontmatterKey,
multiTagSortDir: SortDir.NONE
};
};

Expand Down Expand Up @@ -355,14 +356,16 @@ export const createMultiTagCell = (
options?: {
tagIds?: string[];
hasValidFrontmatter?: boolean;
multiTagSortDir?: SortDir;
}
): MultiTagCell => {
const { tagIds = [], hasValidFrontmatter = null } = options || {};
const { tagIds = [], hasValidFrontmatter = null, multiTagSortDir = SortDir.NONE } = options || {};
return {
id: generateUuid(),
columnId,
tagIds,
hasValidFrontmatter,
multiTagSortDir
};
};

Expand Down
2 changes: 2 additions & 0 deletions src/shared/loom-state/migrate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ export { default as MigrateState17 } from "./migrate-state-17";
export { default as MigrateState18 } from "./migrate-state-18";
export { default as MigrateState19 } from "./migrate-state-19";
export { default as MigrateState20 } from "./migrate-state-20";
export { default as MigrateState21 } from "./migrate-state-21";
export { default as MigrateState22 } from "./migrate-state-22";
4 changes: 2 additions & 2 deletions src/shared/loom-state/migrate/migrate-state-21.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import MigrateState from "./migrate-state";
import { LoomState20, LoomState } from "../types";
import { LoomState20, LoomState21 } from "../types";
import { Row } from "../types/loom-state";

/**
* Migrates to 8.15.6
*/
export default class MigrateState21 implements MigrateState {
public migrate(prevState: LoomState20): LoomState {
public migrate(prevState: LoomState20): LoomState21 {
const { rows } = prevState.model;

const nextRows: Row[] = rows.map((row) => {
Expand Down
28 changes: 28 additions & 0 deletions src/shared/loom-state/migrate/migrate-state-22.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import MigrateState from "./migrate-state";
import { LoomState } from "../types";
import { SortDir, Column } from "../types/loom-state";
import { LoomState21 } from "../types/loom-state-21";

/**
* Migrates to 8.16.0
*/
export default class MigrateState22 implements MigrateState {
public migrate(prevState: LoomState21): LoomState {
const { columns } = prevState.model;

const nextColumns: Column[] = columns.map((column) => {
return {
...column,
multiTagSortDir: SortDir.NONE,
};
});

return {
...prevState,
model: {
...prevState.model,
columns: nextColumns,
},
};
}
}
12 changes: 12 additions & 0 deletions src/shared/loom-state/type-display-names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
DateFilterOption,
SourceType,
DateFormatSeparator,
SortDir,
} from "./types/loom-state";

const getShortDisplayNameForCalculation = (value: GeneralCalculation) => {
Expand Down Expand Up @@ -169,6 +170,17 @@ export const getDisplayNameForDateFormatSeparator = (
}
};

export const getDisplayNameForSortDir = (dir: SortDir) => {
switch (dir) {
case SortDir.ASC:
return "Ascending";
case SortDir.DESC:
return "Descending";
default:
return "Default";
}
}

export const getDisplayNameForCurrencyType = (type: CurrencyType) => {
switch (type) {
case CurrencyType.UNITED_STATES:
Expand Down
1 change: 1 addition & 0 deletions src/shared/loom-state/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export type { LoomState17 } from "./loom-state-17";
export type { LoomState18 } from "./loom-state-18";
export type { LoomState19 } from "./loom-state-19";
export type { LoomState20 } from "./loom-state-20";
export type { LoomState21 } from "./loom-state-21";
Loading

0 comments on commit 919ae14

Please sign in to comment.