Asanaブックマークレットのご紹介

目次:

プロジェクトのすべてのタスクを完了・未完了にする、プロジェクトのセクションをすべて展開する・折りたたむ、タスクのコメントをすべて展開する、といった一括操作をワンクリックで行う方法をご紹介します。

Screen Recording 2022-07-25 at 16.21.00 (1)

0. ブックマークレットとは

ブックマークレットとは、JavaScriptのコードをブラウザーのブックマークに登録して、クリックにより実行できるようにしたものです。JavaScriptコードを「javascript:(function() {」と「})();」で挟むことでブックマークが可能になります。
Asanaを含むWebサイトのフロントエンドは、HTML (部品を表すマークアップ言語)、CSS (レイアウトやデザインを指定する言語)、JavaScript (プログラミング言語) という3つの言語で主に構成されています。
HTMLはタグで囲まれた部品 (ノード) が階層構造になっており、JavaScriptから操作することができます。これはDOM (ドキュメントオブジェクトモデル) と呼ばれる仕組みです。

1. ブックマークレットの追加方法

Asana bookmarklets にアクセスし、青字のリンクをブックマークバーにドラッグ&ドロップして追加してください。
横幅を取らないように、スクリーンショットのようにブックマークレット用のフォルダーを作成してそこに追加していくのがおすすめです。ブックマークバーに直接追加する場合は、名前を編集して絵文字だけにするなど、短くするのがおすすめです。

手作業で登録する場合は、以下のことを行います。

  1. 任意のページをブックマークに登録します。
  2. 登録時に「その他…」をクリックし、保存場所を選択し、名前とURLを編集します。
  3. この投稿の下にあるブックマークのタイトルを「名前」に、javascript:で始まるコードを「URL」に、それぞれ入力します。

ブックマークレットのリストをセクション分けするには、ブックマークのセパレーターツールがおすすめです。Drag meの部分をブックマークにドラッグするだけでセパレーター (横線) を挿入できます。

Asanaのタブを開いた状態で、登録したブックマークレットをクリックすると、自動操作を行えます。

2. 実際のブックマークレット

Asana bookmarklets に記載されているブックマークレットのソースコードと説明です。

2-1. 一つのタスクに対する操作

2-1-1. :speech_balloon: ストーリーのスッキリ表示

以下の「コメントの展開」と「作業間リンクの非表示」を両方行います。

2-1-2. :arrow_up_down: コメントの展開

タスクストーリーの「その他 7 件のコメント」や「もっと見る」をすべてクリックします。

javascript:(function() {
	const expandLink = document.querySelector('.TaskStoryFeed-expandLink');
	if (expandLink && expandLink.textContent.match(/\d/)) expandLink.click();
	document.querySelectorAll('.TruncatedRichText-expand').forEach(link => link.click());
	document.querySelectorAll('.TaskStoryFeed-expandMiniStoriesLink').forEach(link => link.click());
})();

2-1-3. ↔ 作業間リンクの非表示

2-1-4. ⫚ 完了したサブタスクの非表示

右側のタスク詳細ウィンドウで、完了したサブタスクをすべて非表示にします。ブックマークレットをもう一度クリックすると、サブタスクを再表示できます。
サブタスク数が多い場合は、Asana Load MoreというChrome拡張機能をインストールするのもおすすめです。

javascript:(function() {
	const completedSubtaskRows = document.querySelectorAll('.SubtaskTaskRow--completed');
	completedSubtaskRows.forEach(row => {
		row.parentNode.parentNode.style.display = row.parentNode.parentNode.style.display? '': 'none';
	});
})();

2-1-5. :desktop_computer: タスクとメッセージの全幅表示

Asanaのアップデートのおかげで、この機能は半分不要になりました。
タスクを全画面 (Tab+X) 表示にしたとき、「広いビュー」「狭いビュー」の切り替えができるようになりました🙌
タスク一覧の右側にタスクの詳細が表示されるとき、タスクの幅をドラッグで変更できるようになりました🙌
このブックマークレットをクリックすると:

  • 「狭いビュー」も全幅表示になります。
  • メッセージを全画面表示するとき、画面幅いっぱいに表示します。
  • ブックマークレットをもう一度クリックすると、元の幅で表示します。
javascript:(function() {
	const focusModePane = document.querySelector('.Pane.FocusModePage-taskPane');
	if (focusModePane) {
		if (focusModePane.style.flexBasis == 'auto') {
			focusModePane.style.flexBasis = '';
			focusModePane.style.width = '';
		} else {
			focusModePane.style.flexBasis = 'auto';
			focusModePane.style.width = '95%';
		}
	}
	const singleConversationPageCards = document.querySelectorAll('.SingleConversationPage-card');
	const projectConversationsConversationCards = document.querySelectorAll('.ProjectConversations-conversationCard');
	const conversationCards = [...singleConversationPageCards, ...projectConversationsConversationCards];
	if (!conversationCards.length) return;
	if (conversationCards[0].style.width == '95%') {
		conversationCards.forEach(card => card.style.width = '585px');
	} else {
		conversationCards.forEach(card => card.style.width = '95%');
	}
})();

2-2. プロジェクトなどタスクリストに対する操作

:exclamation:注意: タスクが多数あり一画面に表示しきれていない場合は、以下のブックマークレットを実行する前に、Asana画面を一番下までスクロールし、すべてのタスクを読み込んでください。

2-2-1. :arrow_forward:︎ セクションの表示切り替え

リストビューでセクションの展開・折りたたみを切り替えます。

javascript:(function() {
	const firstButtonIcon = document.querySelector('.TaskGroupHeader-toggleButton .Icon');
	if (!firstButtonIcon) return;
	const firstTriangleClassName = firstButtonIcon.classList.contains('DownTriangleIcon')? 'DownTriangleIcon': 'RightTriangleIcon';
	document.querySelectorAll(`.TaskGroupHeader-toggleButton .${firstTriangleClassName}`).forEach(buttonIcon => buttonIcon.parentNode.click());
})();

2-2-2. ▷ サブタスクの表示切り替え

サブタスクの小さい▶︎をクリックし、サブタスクの展開・折りたたみを切り替えます。

  • リストビュー: まず「ソート: なし」に設定します。右側のタスク詳細ウィンドウは閉じている必要があります。サブタスクのあるタスクが多数ある場合にはタスクをリロードし、「他のサブタスクを読み込む」を順にクリックするため時間がかかります。
  • タイムラインビュー: ビューに表示されているサブタスクのみ表示を切り替えられます。画面外のタスクには影響しません。
javascript:(function() {
  const firstTimelineSubtaskToggl = document.querySelector('.TaskTimelineTasks-taskAndSubtasksToggleContainer .MiniIcon');
  if (firstTimelineSubtaskToggl) {
	  const firstCaretClassName = firstTimelineSubtaskToggl.classList.contains('DownCaretMiniIcon')? 'DownCaretMiniIcon': 'RightCaretMiniIcon';
	  document.querySelectorAll(`.MiniIcon.${firstCaretClassName}`).forEach(caretIcon => caretIcon.parentNode.click());
  }

	const triangleDivClassName = '.ProjectSpreadsheetGridRow-subtaskToggleButton';
	const firstListSubtaskButton = document.querySelector(triangleDivClassName);
	if (!firstListSubtaskButton) return;
	const firstTriangleClassName = firstListSubtaskButton.firstElementChild.classList.contains('DownTriangleIcon')? 'DownTriangleIcon': 'RightTriangleIcon';
	const taskPlaceholderHTMLCollection = document.getElementsByClassName('SpreadsheetTaskRowScrollPlaceholder');
	if (taskPlaceholderHTMLCollection.length == 0) {
		const arrayToggleButtons = Array.from(document.querySelectorAll(triangleDivClassName));
		for (var i = 0; i < arrayToggleButtons.length; i++) {
			const arrayToggleButton = arrayToggleButtons[i];
			if (arrayToggleButton.firstElementChild.classList.contains(firstTriangleClassName)) {
				setTimeout(() => {
					arrayToggleButton.click();
				}, 50 * i);
			}
		}
		return;
	}

	const taskGroup = document.querySelector('.TaskGroup');
	const buttonAtTheBottom = document.querySelector('.SpreadsheetPotGridContents-addSectionButton');
	setTimeout(function () {
		if (buttonAtTheBottom) buttonAtTheBottom.scrollIntoView();
	}, 30);
	setTimeout(function () {
		taskGroup.style.display = 'none';
	}, 60);

	let monitorTaskStructure = setInterval(() => {
		if (taskPlaceholderHTMLCollection.length == 0) {
			const arrayToggleButtons = Array.from(document.querySelectorAll(triangleDivClassName));
			for (var i = 0; i < arrayToggleButtons.length; i++) {
				const arrayToggleButton = arrayToggleButtons[i];
				if (arrayToggleButton.firstElementChild.classList.contains(firstTriangleClassName)) {
					setTimeout(() => {
						arrayToggleButton.click();
					}, 5 * i);
				}
			}
			taskGroup.style.display = '';
			clearInterval(monitorTaskStructure);
			const loadMoreLinkHTMLCollection = document.getElementsByClassName('SpreadsheetTaskList-showMoreLink');
			setTimeout(() => {
				let clickingLoadMoreLinks = setInterval(function() {
					if (!loadMoreLinkHTMLCollection.length) {
						clearInterval(clickingLoadMoreLinks);
					} else {
						loadMoreLinkHTMLCollection[0].scrollIntoView();
						loadMoreLinkHTMLCollection[0].click();
					}
				}, 500);
			}, 200);
		}
	}, 100);
})();

2-2-3. :white_check_mark: すべてのタスクの完了

リストビューに表示されているすべての未完了タスクを完了にします。多数ある場合は一度タスクの表示を消したあと、50個ずつクリックしていきます。

javascript:(function() {
	const taskPlaceholderHTMLCollection = document.getElementsByClassName('SpreadsheetTaskRowScrollPlaceholder');
	if (!taskPlaceholderHTMLCollection.length) {
		document.querySelectorAll('.SpreadsheetGridTaskNameAndDetailsCellGroup-completionStatus .TaskRowCompletionStatus-taskCompletionIcon--incomplete').forEach(incompleteIcon => incompleteIcon.parentNode.click());
	} else {
		const taskGroup = document.querySelector('.TaskGroup');
		const buttonAtTheBottom = document.querySelector('.SpreadsheetPotGridContents-addSectionButton');
		setTimeout(function () {if (buttonAtTheBottom) buttonAtTheBottom.scrollIntoView();}, 30);
		setTimeout(function () {
			taskGroup.style.display = 'none';
			const progressIndicator = document.createElement('span');
			progressIndicator.setAttribute('id', 'progressIndicator');
			progressIndicator.textContent = '処理しています';
			taskGroup.parentNode.appendChild(progressIndicator);
		}, 60);

		let monitorTaskStructure = setInterval(() => {
			if (taskPlaceholderHTMLCollection.length == 0) {
				clearInterval(monitorTaskStructure);
				const progressIndicator = document.querySelector('#progressIndicator');
				const allTasks = Array.from(document.querySelectorAll('.SpreadsheetGridTaskNameAndDetailsCellGroup-completionStatus .TaskRowCompletionStatus-taskCompletionIcon--incomplete'));
				const numProcesses = Math.floor(allTasks.length / 50) + 1;
				let counter = 0;
				let loopTasks = setInterval(() => {
					progressIndicator.textContent = `処理しています (${counter}/${numProcesses}) `;

					for (let i = 50 * counter; i < Math.min(allTasks.length, 50 * (counter + 1)); i++) {
						allTasks[i].parentNode.click();
						if (i == allTasks.length - 1) {
							clearInterval(loopTasks);
							progressIndicator.remove();
							taskGroup.style.display = '';
						}
					}
					counter += 1;
				}, 500);
			}
		}, 100);
	}
})();

2-2-4. :ballot_box_with_check: すべてのタスクの未完了

リストビューに表示されているすべての完了タスクを未完了に戻します。多数ある場合は一度タスクの表示を消したあと、50個ずつクリックしていきます。

javascript:(function() {
	const taskPlaceholderHTMLCollection = document.getElementsByClassName('SpreadsheetTaskRowScrollPlaceholder');
	if (!taskPlaceholderHTMLCollection.length) {
		document.querySelectorAll('.SpreadsheetGridTaskNameAndDetailsCellGroup-completionStatus .TaskRowCompletionStatus-taskCompletionIcon--complete').forEach(incompleteIcon => incompleteIcon.parentNode.click());
	} else {
		const taskGroup = document.querySelector('.TaskGroup');
		const buttonAtTheBottom = document.querySelector('.SpreadsheetPotGridContents-addSectionButton');
		setTimeout(function () {if (buttonAtTheBottom) buttonAtTheBottom.scrollIntoView();}, 30);
		setTimeout(function () {
			taskGroup.style.display = 'none';
			const progressIndicator = document.createElement('span');
			progressIndicator.setAttribute('id', 'progressIndicator');
			progressIndicator.textContent = '処理しています';
			taskGroup.parentNode.appendChild(progressIndicator);
		}, 60);

		let monitorTaskStructure = setInterval(() => {
			if (taskPlaceholderHTMLCollection.length == 0) {
				clearInterval(monitorTaskStructure);
				const progressIndicator = document.querySelector('#progressIndicator');
				const allTasks = Array.from(document.querySelectorAll('.SpreadsheetGridTaskNameAndDetailsCellGroup-completionStatus .TaskRowCompletionStatus-taskCompletionIcon--complete'));
				const numProcesses = Math.floor(allTasks.length / 50) + 1;
				let counter = 0;
				let loopTasks = setInterval(() => {
					progressIndicator.textContent = `処理しています (${counter}/${numProcesses}) `;
					for (let i = 50 * counter; i < Math.min(allTasks.length, 50 * (counter + 1)); i++) {
						allTasks[i].parentNode.click();
						if (i == allTasks.length - 1) {
							clearInterval(loopTasks);
							progressIndicator.remove();
							taskGroup.style.display = '';
						}
					}
					counter += 1;
				}, 500);
			}
		}, 100);
	}
})();

2-2-5. :bust_in_silhouette: マイタスクのみ

2-2-6. :spiral_calendar: カレンダータスクの一括展開

カレンダーの月ビューで、「その他 x 件」をすべて開きます。
画面にロードされている日のタスクだけ展開されるので、上下にスクロールすると折り畳まれたままの日が存在します。

javascript:(function() {
  document.querySelectorAll('.CalendarDay-xMoreText').forEach(buttonDiv => buttonDiv.click());
})();

2-3. その他の操作

2-3-1. ☰ サイドバーのサイズ変更

2-3-2. :link: タイトルとURLのコピー

ウェブページのリンクをAsanaに貼るとき、以下のように四度手間になっていませんか?

  1. タイトルをコピー
  2. タイトルをペースト
  3. URLをコピー
  4. URLをペースト

この二ステップで手間を省きましょう!

  1. ブックマークレットをクリック
  2. リンクをペースト

Asana以外にリンクを貼るときにも使えます。

ブックマークレットをクリックした直後にカーソルを動かすと、URLしかコピーできない場合があります。クリックが完了するまで、気持ち長めにカーソルを止めておくのがコツです。

javascript:(function() {
  const url = window.location.href;
  const title = document.title;
  const link = `<a href="${url}">${title}</a>`;
  const blobHtml = new Blob([link], {type: 'text/html'});
  const blobText = new Blob([url], {type: 'text/plain'});
  const data = [new ClipboardItem({
    ['text/plain']: blobText,
    ['text/html']: blobHtml
  })];
  navigator.clipboard.write(data);
})();

3. 工夫が必要だったところ

3-1. プレースホルダータスク

プロジェクトに多数のタスクがあるとき、Asanaは表示範囲から遠く離れたタスクを「タスク名だけ」のプレースホルダーの状態に簡略化してリソース (メモリやエネルギー使用量) を節約しています。その近くにスクロールすると、再度データが読み込まれます。

例: プロジェクトの一番下からスクロールしていくと、上の方のタスクが一瞬「タスク名のみ」の状態で表示され、コンマ数秒後にフル表示されます。

セクション2-2のように「すべてのタスク」を対象にする場合は、一度すべてのタスクを非表示にして、Asanaに「すべてのタスクを表示するだけの十分なスペースがあるんだ」と信じ込ませます。Asanaがすべてのプレースホルダーを完全なタスクの形に書き直したとき、処理を実行し、非表示を解除します。

3-2. 負荷の軽減

一度に行う処理が多すぎると、Asanaのサーバーに負荷がかかりすぎてしまいます。APIを使用するときも、タスクを複数選択して一括操作するときも、おおよそ数十タスクごとに処理を行うので、上記「すべてのタスクの完了・未完了」では、50個ずつ処理するようにしました。

4. 他の方法との比較

4-1. JavaScriptを使用する方法との比較

Asanaで自動化を行う方法を比較してみました。左にあるほど複雑・強力な方法であり、右に行くほど簡単な方法です。ブックマークレットはChrome拡張機能を作る1/100〜1/10くらいのコード行数で済むので、かなり気軽な方法です。セクション3の問題を考慮すると少々長くなります。

方法: OAuth 個人アクセストークン (PAT) Chrome拡張 ブックマークレット アドレスバー
例: Asana AcademyにAsanaアカウントでログイン Asana公式拡張機能 このトピックに記載 ワークスペースの一覧を取得
認証方法: サーバーを立てる PATをハードコードまたは環境変数に保存する ログインしていることを示すブラウザーのCookie Cookie (同左) Cookie (同左)
利用方法: アクセスを認可 PATを利用 Chrome Web Storeからインストール ブックマークに追加 アドレスバーにURLを入力
できること: APIを通じた操作 APIを通じた操作 APIを通じた操作+DOMの操作 DOMの操作 APIを通じたGET操作 (情報の取得)
得意なこと: 大規模なツールに最適 自分用にスクリプトを書くときに便利 配布が楽 作成・配布が楽 最も気軽
できないこと: DOMの操作 DOMの操作 (少しはあります) 表示されていないタスクの操作 POST/PUT/DELETE操作 (情報の編集)
データが多い場合: ページネーション ページネーション ページネーション プレースホルダータスク ページネーション (自動化できない)

例: プロジェクトのタスクをすべて完了にする
この場合、ブックマークレットを使った方がシンプルな方法で高速に処理が行えます。

  • APIを利用する方法では、/projects/<project_gid>/tasks エンドポイントへのGETリクエストでタスクを取得し、forループで各タスクを完了するPUTリクエストを書きます。タスクの取得と更新で2回APIコールを行う必要があります。
  • ブックマークレットでは、画面に表示されているタスクを直接ループしてクリックします。

4-2. JavaScriptとCSSの比較

CSSを利用してデザインをカスタマイズすることもできます。JavaScriptとの大きな違いは以下のとおりです。

  • APIを使用しないので認証不要
  • HTML要素のデザインを常時変更しておける
  • 特定の変化が起きた場合、または特定の操作を行った場合に動的に対応することはできない
    利用方法: StylishUser CSSなどのChrome拡張機能をインストールします。userstyles.orgなどから別のユーザーが作成したCSSを利用することも、自分でCSSをカスタマイズすることもできます。

例: サイドバーの幅を変更する

  • 上記2-3-1のブックマークレットを使用した方法では、ボタンを押したときにサイドバーの拡大・縮小が行えます。
  • サイドバーの幅を常に変更しておきたい場合は、CSSをカスタマイズする方法が適しています。

5. 規約等の考慮

5-1. リバースエンジニアリング

AsanaのAPI規約でリバースエンジニアリングは禁止されています。ただし、右クリック > 「要素を検証」でDOM要素を特定する行為は一般に簡単に行えるものであり、Asanaの機密には何ら関わらない方法だと考えています。

5-2. デザインの変更可能性

AsanaツールのHTML要素を特定するためのIDやクラス名は、Asanaがいつでも自由に変更できます。その場合には上記のブックマークレットが機能しなくなります。気付き次第アップデートしますが、問題にお気づきの方がいらっしゃれば下の「返信」でお知らせください。

5-3. 免責

ブックマークレットの作成には細心の注意を払い、テストをおこなっていますが、それに基づくいかなる問題への責任も開発者は負えません。

6. 謝辞

  • ブックマークレットのアイデアは元々 "COLLAPSE (or re-expand) ALL SECTIONS" button needed - #4 by Tony_Tsui を見たときに便利で簡単に応用できる方法だと思いました。"COLLAPSE (or re-expand) ALL SECTIONS" button needed - #47 by Skyler には別のユーザーがまとめたブックマークレットもあります。
  • フォーラムリーダーのBastienさんとアンバサダーのItayさんに実際に試していただき、上記「工夫が必要だったところ」の課題に気づくことができました。
  • お読みいただきありがとうございます。他に欲しい機能などあれば、コメントをお願いいたします。JavaScriptを書ける方は、ぜひご自分でもブックマークレットを作ってみてください。
9 Likes

@ShunS さん、素晴らしい機能を構築いただきありがとうございます :clap:
非エンジニアの私でも、JavaScriptのコードをブックマークするだけという簡単な手順で実現できました。素晴らしいですね、感動しております :smiling_face_with_three_hearts:
コメントやサブタスクの一括展開機能や、作業間リンクが多い場合はストーリーのスッキリ表示を、私はとても活用できそうです :rocket:
この機能、いろんな方の要望を満たしそうですね。ぜひ使ってみた方はコメントいただけると嬉しいです。

2 Likes

お褒めいただきありがとうございます :slight_smile:

完了したサブタスクを、タスク内冒頭のリストでも非表示にしたい を読み、いくつかアップデートしました。

他にもご要望やアイデアがあれば、どしどしお寄せください :bulb:

3 Likes

アップデート:

他の人もブックマークレットを作っていて、さらに便利にAsanaを使えるようになるので嬉しいです✨

2 Likes

アップデート:

2 Likes

@ShunS さん、コードはさっぱり分からない私でも、リンクをブックマークバーにドラッグ&ドロップするだけで、簡単にできました :raised_hands:
:speech_balloon: ストーリーのスッキリ表示」と「 :desktop_computer: タスクの全幅表示」がワンクリックで出来て、さらに快適に作業できるようになりました :tada:

:musical_note: Vivaldi Browserでも使えると、うれしいです :musical_note:

1 Like

@anon57947127 さん、ブックマークレットお使いいただきありがとうございます🙌

Vivaldiで使う方法を試してみました。
まず、設定 > Address Bar > Security Featuresで、Strip JavaScript from Pasted Textのチェックを外す必要がありそうです。

  1. ブックマークレットをドラッグして追加すると、リンクが about:blank#blocked になります
  2. ブックマークレットを右クリックして Copy Link Address します
  3. about:blank#blocked になっているところにJavaScriptコードを貼り付けます
  4. ブックマークのアイコンが地球儀からコードファイルに変わり、登録できたことを確認できます

登録の手間が増えますが、これで、Asanaページを開いているとき、ブックマークレットをクリック(2回?)すると、無事に実行されます。

ChromeとVivaldiでCSSの扱いが違うようで、「2-1-5. :desktop_computer: タスクの全幅表示」などの挙動が違うようです。ただし、Asanaの対応外のブラウザーを完全にはサポートできませんので、ご容赦ください!

1 Like

アップデート:

2 Likes

@ShunS さん、お忙しいところ Vivaldi Browser で使う方法まで、ありがとうございます :notes: ぜひ試してみます :exclamation:

2 Likes

アップデート:

@Tomohiro_Oka さん、本日のAUAでご提案いただきありがとうございました🙌

2 Likes

@ShunS
早速、タスク詳細の幅可変を実現いただき、ありがとうございます!
便利に使わせて頂いています!

2 Likes

@ShunS
はじめまして、簡単に登録できて素晴らしいですね

タイムラインビューでも例えば特定のセクションを折りたたむとかは
頑張ればできるものでしょうか?

2 Likes

@かんの さん、メッセージいただきありがとうございます!

はい、できると思います。
タイムラインビューのセクションの折りたたみでしたら、
TimelineGroupHeader-toggleButton クラスで要素を見つけてクリックするのがよさそうです。
「特定のセクション」を見つけるには、上から何番目か(インデックス)を使うか、セクション名を指定するのがよさそうですね。

何かヘルプが必要そうでしたら、またリストに追加できそうなブックマークレットがありましたら、お知らせください!

1 Like

アップデート:

1 Like

サブタスクの表示切替、便利です。ありがとうございます!
要望といいますか、相談させてください。

プロジェクト全体のタスクをカレンダーで見たいのです、複数タスクがあると、畳まれてしまいます。
ブックマークレットで全て畳み込みなしで、タスク表示させることは可能なのでしょうか?

2 Likes

@Kanako_Ueno さん、ご要望&ご相談ありがとうございました。
さっそく実装しました!
プロジェクトとマイタスクの月ビューのカレンダーで、ブックマークレットを押すと、表示されている範囲のタスクが展開されるようになったはずです。
最初から展開した状態にするにはブックマークレットでは力不足で、Chrome拡張などが必要なので、ワンクリックは必要になります :bow:

アップデート:

1 Like

@ShunS さん

早速ありがとうございます!
素晴らしいです!今までポチポチポチポチ繰り返していたので、とても助かります!

本当に感謝しかありません :blush:

1 Like

アップデート:

新しいバージョンを利用するには、 Asana Bookmarklets から新しいブックマークレットをバーにドラッグしてください。

3 Likes

アップデート:

新しいバージョンは Asana Bookmarklets からご利用ください :slight_smile:

3 Likes

Asanaの営業の方から連絡があり、今回ブックマークレットを知りました。
いろいろな操作がワンクリックでできて、便利な仕組みだと思います。

サブタスクの表示切替について要望来ていましたので、アップデートありがとうございました。

2 Likes