Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add setting for embedded add task button behaviour #353

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ default Obsidian theme.

- Rebuilt the task renderer from the ground up. This now resembles Todoist more closely and has improved the default styling.
- Added support for translations in the plugin
- Added a setting to control whether the embedded "Add task" button in a query should automatically add a link to the current page.
- This behaviour can now be turned off or configured to append to the task name or description.

### 🔁 Changes

Expand Down
4 changes: 4 additions & 0 deletions docs/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ When enabled, queries will render an icon accompanying the labels.

When enabled, page links added to tasks created via the [command](./commands/add-task) will be wrapped in parenthesis. This may help identifying links if you primarily use Todoist on mobile platforms.

### Add task button adds page link

When enabled, the embedded add task button in queries will add a link to the page to the task in the specified place. This behaviour can also be disabled completely.

## Advanced

### Debug logging
Expand Down
2 changes: 1 addition & 1 deletion plugin/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const commands = {
"add-task-page-description": addTaskWithPageInDescription,
};

type CommandId = keyof typeof commands;
export type CommandId = keyof typeof commands;

export const registerCommands = (plugin: TodoistPlugin) => {
const i18n = t().commands;
Expand Down
10 changes: 10 additions & 0 deletions plugin/src/i18n/langs/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ export const en: Translations = {
description:
"When enabled, wraps Obsidian page links in Todoist tasks created from the command",
},
addTaskButtonAddsPageLink: {
label: "Add task button adds page link",
description:
"When enabled, the embedded add task button in queries will add a link to the page to the task in the specified place",
options: {
off: "Disabled",
description: "Task description",
content: "Task name",
},
},
},
advanced: {
header: "Advanced",
Expand Down
9 changes: 9 additions & 0 deletions plugin/src/i18n/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ export type Translations = {
label: string;
description: string;
};
addTaskButtonAddsPageLink: {
label: string;
description: string;
options: {
off: string;
description: string;
content: string;
};
};
};
advanced: {
header: string;
Expand Down
4 changes: 4 additions & 0 deletions plugin/src/settings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { create } from "zustand";

export type AddPageLinkSetting = "off" | "description" | "content";

const defaultSettings: Settings = {
fadeToggle: true,

Expand All @@ -11,6 +13,7 @@ const defaultSettings: Settings = {
renderLabelsIcon: true,

shouldWrapLinksInParens: false,
addTaskButtonAddsPageLink: "content",

debugLogging: false,
};
Expand All @@ -27,6 +30,7 @@ export type Settings = {
renderLabelsIcon: boolean;

shouldWrapLinksInParens: boolean;
addTaskButtonAddsPageLink: AddPageLinkSetting;

debugLogging: boolean;
};
Expand Down
18 changes: 16 additions & 2 deletions plugin/src/ui/query/QueryHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { fireCommand } from "@/commands";
import { type CommandId, fireCommand } from "@/commands";
import { type Settings, useSettingsStore } from "@/settings";
import { ObsidianIcon } from "@/ui/components/obsidian-icon";
import { MarkdownEditButtonContext, PluginContext } from "@/ui/context";
import classNames from "classnames";
import type React from "react";
import { Button } from "react-aria-components";

const getAddTaskCommandId = (settings: Settings): CommandId => {
switch (settings.addTaskButtonAddsPageLink) {
case "content":
return "add-task-page-content";
case "description":
return "add-task-page-description";
case "off":
return "add-task";
}
};

type Props = {
title: string;
isFetching: boolean;
Expand All @@ -15,14 +27,16 @@ export const QueryHeader: React.FC<Props> = ({ title, isFetching, refresh }) =>
const plugin = PluginContext.use();
const { click: editBlock } = MarkdownEditButtonContext.use()();

const settings = useSettingsStore();

return (
<div className="todoist-query-header">
<span className="todoist-query-title">{title}</span>
<div className="todoist-query-controls">
<HeaderButton
className="add-task"
iconId="plus"
action={() => fireCommand("add-task-page-content", plugin)}
action={() => fireCommand(getAddTaskCommandId(settings), plugin)}
/>
<HeaderButton
className={classNames("refresh-query", { "is-refreshing": isFetching })}
Expand Down
35 changes: 34 additions & 1 deletion plugin/src/ui/settings/SettingItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { t } from "@/i18n";
import classNames from "classnames";
import type { PropsWithChildren } from "react";
import type { OptionHTMLAttributes, PropsWithChildren } from "react";
import type React from "react";
import { useState } from "react";
import { ObsidianIcon } from "../components/obsidian-icon";
Expand Down Expand Up @@ -82,8 +82,41 @@ const ToggleControl: React.FC<ToggleControl> = ({ value, onClick }) => {
return <div className={className} onClick={onToggle} onKeyDown={onToggle} />;
};

type DropdownOptionValue = OptionHTMLAttributes<HTMLOptionElement>["value"];

type DropdownControlProps<T extends DropdownOptionValue> = {
value: T;
options: { label: string; value: T }[];
onClick: (val: T) => Promise<void>;
};

const DropdownControl = <T extends DropdownOptionValue>({
value,
options,
onClick,
}: DropdownControlProps<T>): React.ReactNode => {
const [selected, setSelected] = useState(value);

const onChange = async (ev: React.ChangeEvent<HTMLSelectElement>) => {
const val = ev.target.value as T;
setSelected(val);
await onClick(val);
};

return (
<select className="dropdown" value={selected} onChange={onChange}>
{options.map(({ label, value }) => (
<option key={label} value={value}>
{label}
</option>
))}
</select>
);
};

export const Setting = {
Root: Root,
ButtonControl: ButtonControl,
ToggleControl: ToggleControl,
DropdownControl: DropdownControl,
};
27 changes: 27 additions & 0 deletions plugin/src/ui/settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,33 @@ const SettingsRoot: React.FC<Props> = ({ plugin }) => {
>
<Setting.ToggleControl {...toggleProps("shouldWrapLinksInParens")} />
</Setting.Root>
<Setting.Root
name={i18n.taskCreation.addTaskButtonAddsPageLink.label}
description={i18n.taskCreation.addTaskButtonAddsPageLink.description}
>
<Setting.DropdownControl
value={settings.addTaskButtonAddsPageLink}
options={[
{
label: i18n.taskCreation.addTaskButtonAddsPageLink.options.off,
value: "off",
},
{
label: i18n.taskCreation.addTaskButtonAddsPageLink.options.description,
value: "description",
},
{
label: i18n.taskCreation.addTaskButtonAddsPageLink.options.content,
value: "content",
},
]}
onClick={async (val) => {
await plugin.writeOptions({
addTaskButtonAddsPageLink: val,
});
}}
/>
</Setting.Root>

<h2>{i18n.advanced.header}</h2>
<Setting.Root
Expand Down