Implement subtasks view and settings option,

clean up CSS
This commit is contained in:
ransurf 2022-01-13 12:47:36 -08:00
parent 0ac05ef6d3
commit 916236db5d
13 changed files with 257 additions and 90 deletions

View file

@ -6,6 +6,7 @@ interface HabiticaSyncSettings {
userID: string userID: string
apiToken: string apiToken: string
showTaskDescription: boolean showTaskDescription: boolean
showSubTasks: boolean
} }
const DEFAULT_SETTINGS: Partial<HabiticaSyncSettings> = { const DEFAULT_SETTINGS: Partial<HabiticaSyncSettings> = {
userID: "", userID: "",

View file

@ -51,5 +51,17 @@ export class HabiticaSyncSettingsTab extends PluginSettingTab {
}) })
}); });
new Setting(containerEl)
.setName("Show Sub-Tasks")
.setDesc("Updates require pane re-opening")
.addToggle(cb => {
cb
.setValue(this.plugin.settings.showSubTasks)
.onChange(async (isEnable) => {
this.plugin.settings.showSubTasks = isEnable;
await this.plugin.saveSettings();
})
});
} }
} }

View file

@ -194,9 +194,10 @@ class App extends React.Component<any, any> {
else { else {
return (<div className="plugin-root"> return (<div className="plugin-root">
{content} {content}
<Statsview className ="stats-view" user_data={this.state.user_data} />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" /> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<Taskview data={this.state.tasks} handleChangeTodos={this.handleChangeTodos} settings = {this.props.plugin.settings} handleChangeDailys={this.handleChangeDailys} handleChangeHabits={this.handleChangeHabits} handleChangeRewards={this.handleChangeRewards}/> <Taskview data={this.state.tasks} handleChangeTodos={this.handleChangeTodos} settings = {this.props.plugin.settings} handleChangeDailys={this.handleChangeDailys} handleChangeHabits={this.handleChangeHabits} handleChangeRewards={this.handleChangeRewards}/>
<Statsview user_data={this.state.user_data} />
</div> </div>
); );
} }

View file

@ -4,7 +4,6 @@ export default function Index(props: any) {
return( return(
<div className="stats"> <div className="stats">
{/* <div id="profile-name">{props.user_data.profile.name}</div> */} {/* <div id="profile-name">{props.user_data.profile.name}</div> */}
{console.log(props)}
<div className = "substats" id="hp">HP: {(props.user_data.stats.hp).toPrecision(3)}</div> <div className = "substats" id="hp">HP: {(props.user_data.stats.hp).toPrecision(3)}</div>
<div className = "substats" id="lvl">LEVEL: {props.user_data.stats.lvl}</div> <div className = "substats" id="lvl">LEVEL: {props.user_data.stats.lvl}</div>
<div className = "substats" id="gold">GOLD: {(props.user_data.stats.gp).toPrecision(3)}</div> <div className = "substats" id="gold">GOLD: {(props.user_data.stats.gp).toPrecision(3)}</div>

View file

@ -1,6 +1,7 @@
import Emoji from "react-emoji-render"; import Emoji from "react-emoji-render";
import * as React from "react"; import * as React from "react";
import ReactMarkdown from "react-markdown"; import ReactMarkdown from "react-markdown";
import DailySubTasks from "./DailySubTasks";
function DailyItem(props: any) { function DailyItem(props: any) {
return ( return (
@ -8,7 +9,9 @@ function DailyItem(props: any) {
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed} /> <input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed} />
<div> <div>
<p><Emoji text={props.daily_text}></Emoji></p> <p><Emoji text={props.daily_text}></Emoji></p>
<ReactMarkdown children={props.daily_notes} /> <ReactMarkdown className="description" children={props.daily_notes} />
{console.log(props.checklist)}
<DailySubTasks subtasks={props.daily_subtasks} onChange={props.onChange}></DailySubTasks>
</div> </div>
</div> </div>

View file

@ -0,0 +1,20 @@
import Emoji from "react-emoji-render";
import * as React from "react";
function DailySubTasks(props: any) {
if (props.subtasks) {
const subtasks = props.subtasks.map((subtask: any) => {
return (
<div className="subtask" id={subtask.id}>
<input type="checkbox" className="checkbox" onChange={props.onChange} checked={subtask.completed} />
<p id={subtask.id}><Emoji text={subtask.text}></Emoji></p>
</div>
)
});
return subtasks
}
else {
return <div></div>
}
}
export default DailySubTasks

View file

@ -8,11 +8,19 @@ export default function Index(props: any){
} }
else { else {
const incompleteDailies = props.dailys.map((daily: any) => { const incompleteDailies = props.dailys.map((daily: any) => {
if(!daily.completed) if (!daily.completed) {
let daily_notes = '';
let daily_subtasks = '';
if (props.settings.showTaskDescription) { if (props.settings.showTaskDescription) {
return <DailyItem key={daily.id} id={daily.id} daily_text={daily.text} daily_notes={daily.notes} onChange={props.onChange} completed={daily.completed}/> daily_notes = daily.notes;
} else { }
return <DailyItem key={daily.id} id={daily.id} daily_text={daily.text} onChange={props.onChange} completed={daily.completed}/>
if (props.settings.showSubTasks) {
daily_subtasks = daily.checklist;
}
return <DailyItem key={daily.id} id={daily.id} daily_text={daily.text}
daily_notes={daily_notes} daily_subtasks={daily_subtasks}
onChange={props.onChange} completed={daily.completed}/>
} }
}) })
const completedDailies = props.dailys.map((daily: any) => { const completedDailies = props.dailys.map((daily: any) => {

View file

@ -5,15 +5,17 @@ import ReactMarkdown from "react-markdown";
function HabitItem(props: any) { function HabitItem(props: any) {
return ( return (
<div className="habit-item" id={props.id}> <div className="habit-item" id={props.id}>
<button className="habit-plus" id={"plus" + props.id} onClick={props.onChange}> <div className="habit-button-grp">
<button className="habit-button" id={"plus" + props.id} onClick={props.onChange}>
+{props.upCount} +{props.upCount}
</button> </button>
<button className="habit-minus" id={"mins" + props.id} onClick={props.onChange}> <button className="habit-button" id={"mins" + props.id} onClick={props.onChange}>
-{props.downCount} -{props.downCount}
</button> </button>
</div>
<div> <div>
<p className="habit-text"><Emoji text={props.habit_text}></Emoji></p> <p className="habit-text"><Emoji text={props.habit_text}></Emoji></p>
<ReactMarkdown children={props.habit_notes} /> <ReactMarkdown className="description" children={props.habit_notes} />
</div> </div>
</div> </div>
) )

View file

@ -3,11 +3,13 @@ import * as React from "react";
import ReactMarkdown from "react-markdown"; import ReactMarkdown from "react-markdown";
function RewardItem(props: any) { function RewardItem(props: any) {
return ( return (
<div className="reward-item" id={props.id}> <div className="habit-item" id={props.id}>
<button className="reward-click" id={props.id} onClick={props.onChange}>-{props.reward_value}</button> <div className="habit-button-grp">
<button className="habit-button" id={props.id} onClick={props.onChange}>-{props.reward_value}</button>
</div>
<div> <div>
<p className="reward-text"><Emoji text={props.reward_text}></Emoji></p> <p className="habit-text"><Emoji text={props.reward_text}></Emoji></p>
<ReactMarkdown children={props.reward_notes} /> <ReactMarkdown className="description" children={props.reward_notes} />
</div> </div>
</div> </div>

View file

@ -1,6 +1,7 @@
import Emoji from "react-emoji-render"; import Emoji from "react-emoji-render";
import * as React from "react"; import * as React from "react";
import ReactMarkdown from "react-markdown"; import ReactMarkdown from "react-markdown";
import TodoSubTasks from "./TodoSubTasks";
function TodoItem(props: any) { function TodoItem(props: any) {
return ( return (
@ -9,7 +10,8 @@ function TodoItem(props: any) {
{/* <p><Emoji text ={props.todo_text}></Emoji></p> */} {/* <p><Emoji text ={props.todo_text}></Emoji></p> */}
<div> <div>
<p><Emoji text={props.todo_text}></Emoji></p> <p><Emoji text={props.todo_text}></Emoji></p>
<ReactMarkdown children={props.todo_notes} /> <ReactMarkdown className="description" children={props.todo_notes} />
<TodoSubTasks subtasks={props.todo_subtasks} onChange={props.onChange}></TodoSubTasks>
</div> </div>
</div> </div>
) )

View file

@ -0,0 +1,20 @@
import Emoji from "react-emoji-render";
import * as React from "react";
function TodoSubTasks(props: any) {
if (props.subtasks) {
const subtasks = props.subtasks.map((subtask: any) => {
return (
<div className="subtask" id={subtask.id}>
<input type="checkbox" className="checkbox" onChange={props.onChange} checked={subtask.completed} />
<p id={subtask.id}><Emoji text={subtask.text}></Emoji></p>
</div>
)
});
return subtasks
}
else {
return <div></div>
}
}
export default TodoSubTasks

View file

@ -8,12 +8,20 @@ export default function Index(props: any){
} }
else { else {
const incompleteTodos = props.todos.map((todo: any) => { const incompleteTodos = props.todos.map((todo: any) => {
if(!todo.completed) { if(!todo.completed) {
let todo_notes = '';
let todo_subtasks = '';
if (props.settings.showTaskDescription) { if (props.settings.showTaskDescription) {
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} todo_notes={todo.notes} onChange={props.onChange} completed={todo.completed}/> todo_notes = todo.notes;
} else {
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} onChange={props.onChange} completed={todo.completed}/>
} }
if (props.settings.showSubTasks) {
todo_subtasks = todo.checklist;
}
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text}
todo_notes={todo_subtasks} todo_subtasks={todo_subtasks}
onChange={props.onChange} completed={todo.completed}/>
} }
}) })

View file

@ -1,103 +1,156 @@
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@1,300&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Open Sans:ital,wght@0,400;1,100&family=Roboto&display=swap');
* {
padding: 0;
}
.add-task-input {
display: flex;
}
#profile-name {
font-size: x-large;
font-weight: bold;
padding-bottom: 3%;
}
.stats { .stats {
width: 95%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
font-weight: bold;
padding-bottom: 5px;
}
.stats-view {
border-bottom: 1px;
}
.modify-todo {
align-self: center;
}
.delete-todo {
align-self: center;
} }
.todo-item { .todo-item {
display: flex; display: grid;
justify-content: flex-start; grid-template-columns: 1fr 30fr 1fr 1fr;
align-items: center; justify-content: left;
padding: 0px 0px 0; align-items: flex-start;
padding-top: 5px;
padding-bottom: 5px;
width: 100%; width: 100%;
border-bottom: 1px solid #cecece; border-bottom: 1px solid #cecece;
font-family: Roboto, sans-serif; font-family: Roboto, sans-serif;
font-weight: normal; font-weight: bold;
font-size: 16px; font-size: 16px;
} }
.reward-item { .description {
display: flex; font-family: Open Sans, sans-serif;
justify-content: flex-start; font-style: italic;
align-items: center; font-weight: 100;
padding: 0px 0px 0; }
width: 100%; .description > ul {
border-bottom: 1px solid #cecece; list-style-type: none;
font-family: Roboto, sans-serif; }
font-weight: normal; p {
font-size: 16px; margin: 0;
} }
.habit-text { .habit-text {
text-align: left !important; text-align: left !important;
padding: 0px; font-weight: bold;
padding-top: 5px;
width: 80%;
margin-right: 20px; margin-right: 20px;
} }
.habit-plus { .habit-button {
/* background-color: #fff; */ /* background-color: #fff; */
border: none; border: none;
/* color: black; */ /* color: black; */
padding: 7px 5px;
width: 40px;
text-align: center; text-align: center;
text-decoration: none; text-decoration: none;
font-size: 16px; font-size: 16px;
} display: block;
width: 100%;
.habit-minus {
/* background-color: #fff; */
/* border-radius: 50%; */
border: none;
/* color: black; */
padding: 7px 5px;
text-align: center;
text-decoration: none;
font-size: 16px;
width: 40px;
} }
.habit-item { .habit-item {
display: flex; display: flex;
/* justify-content: center; */ grid-template-columns: 60px 1fr;
align-content: space-between;
align-items: center;
padding: 0px 0px 0;
width: 100%; width: 100%;
gap: 5px;
border-bottom: 1px solid #cecece; border-bottom: 1px solid #cecece;
font-family: Roboto, sans-serif; font-family: Open Sans, sans-serif;
font-weight: 50%; font-weight: 100%;
font-size: 16px; font-size: 16px;
padding-top: 5px;
padding-bottom: 5px;
}
.habit-button-grp {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-content: stretch;
height: 100%;
} }
input[type=checkbox] { input[type=checkbox] {
margin-right: 10px; margin-right: 10px;
margin-top: 5px;
align-self: start;
}
.todo-content {
align-self: center;
}
.submit-button {
/* padding: 5px 5px; */
font-size: 15px;
border: 1px solid #aaa;
/* white-space: nowrap; */
/* margin: 10px; */
margin: 0;
} }
input[type=checkbox]:focus { input[type=checkbox]:focus {
outline: 0; outline: 0;
} }
.task-view {
overflow: scroll;
}
::-webkit-scrollbar { ::-webkit-scrollbar {
display: none; /* Chrome Safari */ display: none; /* Chrome Safari */
} }
.plugin-root { .plugin-root {
min-width: 260px; min-width: 260px;
display: grid; display: flex;
grid-template-rows: auto 1fr auto; flex-direction: column;
height: inherit; justify-content: flex-start;
align-items: center;
}
#classDisplay {
height: 100%;
}
.view-content {
margin-bottom: 0;
} }
.substats { .substats {
font-size: medium; font-size: medium;
} }
ul {
margin: 0;
}
/* react-tabs internal file :wink: */ /* react-tabs internal file :wink: */
.material-icons { .material-icons {
font-size: 12px !important; font-size: 12px !important;
@ -114,12 +167,12 @@ input[type=checkbox]:focus {
.react-tabs { .react-tabs {
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
height: 100%;
} }
.react-tabs__tab-list { .react-tabs__tab-list {
border-bottom: 1px solid #aaa; border-bottom: 1px solid #aaa;
margin: 0 0 10px; margin: 0 0 5px;
padding: 0; padding: 0;
} }
@ -165,6 +218,13 @@ input[type=checkbox]:focus {
.react-tabs__tab-panel { .react-tabs__tab-panel {
display: none; display: none;
left: 0px; left: 0px;
height: 88%;
/* overflow: scroll; */
}
.task-panel {
overflow: scroll;
height: 100%;
} }
.react-tabs__tab-panel--selected { .react-tabs__tab-panel--selected {
@ -180,12 +240,47 @@ ul li:not(.task-list-item)::before {
font-weight: bold; font-weight: bold;
text-shadow: 0 0 0.5em transparent; text-shadow: 0 0 0.5em transparent;
} }
body > div.app-container.is-left-sidedock-collapsed.is-right-sidedock-collapsed > div.horizontal-main-container > div > div.workspace-split.mod-horizontal.mod-right-split > div.workspace-tabs > div.workspace-leaf > div > div.view-content > div > div.cron > button {
.task-operation {
align-self: center;
margin: 0;
padding: 0;
}
.edit-item {
display: flex;
flex-direction: column;
width: 100%;
}
.edit-button {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.task-submit {
display: grid;
grid-template-columns: 10fr 5fr;
}
.add-task-input {
display: block;
width: 100%;
}
.task-input-box {
margin-right: 10px;
}
button {
margin: auto; margin: auto;
margin-bottom: 5px; margin-bottom: 5px;
white-space: nowrap;
padding: 5px 5px;
margin-right: 0;
} }
.cron { .cron {
height: fit-content;
display: inline-grid; display: inline-grid;
justify-content: center; justify-content: center;
text-align: center;; text-align: center;;
@ -193,7 +288,6 @@ body > div.app-container.is-left-sidedock-collapsed.is-right-sidedock-collapsed
margin-left: 10%; margin-left: 10%;
margin-right: 10%; margin-right: 10%;
margin-bottom: 10px; margin-bottom: 10px;
background-color: var(--background-primary-alt);
border-radius: 10px; border-radius: 10px;
} }
#cronMessage { #cronMessage {
@ -202,15 +296,10 @@ body > div.app-container.is-left-sidedock-collapsed.is-right-sidedock-collapsed
color: var(--text-normal) color: var(--text-normal)
} }
button { .subtask {
color: var(--text-normal); display: flex;
background-color: var(--background-secondary-alt); flex-direction: row;
border-radius: 4px; font-weight: normal;
border: none; font-family: Roboto, sans-serif;
padding: 6px 20px; justify-content: flex-start;
cursor: pointer;
margin-right: 12px;
font-family: 'Inter', sans-serif;
outline: none;
user-select: none;
} }