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

Progress bar UX Improvements #449

Merged
merged 18 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from 17 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
51 changes: 51 additions & 0 deletions app/components/progress-bar.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<div ...attributes class='progress-slider'>
<input
{{focus-when this.isEditable}}
aria-label='progress slider for IN-Progress tasks'
data-test-progress-bar
class='progress-slider__input-slider'
id='progress-slider-input'
type='range'
value={{@value}}
min='0'
max='100'
step='10'
{{on 'change' this.onChange}}
{{on 'input' this.onInput}}
disabled={{not this.isEditable}}
/>
<button
data-test-progress-bar-button
{{on 'click' this.turnEditModeOn}}
class='progress-slider__button
{{unless this.isEditable "progress-slider__button--hover"}}'
type='button'
>
{{#if this.isEditable}}
<span class='progress-slider__button__text'>{{@value}}</span>
{{else}}
<svg
class='progress-slider__button__edit-icon'
viewBox='0 0 24 24'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
class='progress-slider__button__edit-icon__inner'
opacity='0.5'
d='M4 20H8L18 10L14 6L4 16V20Z'
fill='#000000'
/>
<path
class='progress-slider__button__edit-icon__outer'
d='M18 10L21 7L17 3L14 6M18 10L8 20H4V16L14 6M18 10L14 6'
stroke='#000000'
stroke-width='1.5'
stroke-linecap='round'
stroke-linejoin='round'
/>
</svg>
{{/if}}
</button>

</div>
47 changes: 47 additions & 0 deletions app/components/progress-bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { later, debounce } from '@ember/runloop';

export default class ProgressBarComponent extends Component {
@tracked isEditable = false;
@tracked value = this.args.value;
lastEditTime = null;

@action turnEditModeOn() {
this.isEditable = true;
this.lastEditTime = Date.now();
this.setEditableToFalse();
}

setEditableToFalse() {
later(() => {
const timeDelta = Date.now() - this.lastEditTime;
if (this.isEditable && timeDelta >= 5000) {
this.isEditable = false;
} else if (this.isEditable) {
this.setEditableToFalse();
}
}, 5000);
}

@action onInput(e) {
this.lastEditTime = Date.now();
this.value = e.target.value;
if (this.args.onInput) {
this.args.onInput(this.value);
}
}

@action onChange(e) {
this.lastEditTime = Date.now();
if (this.args.onChange) {
debounce(this, this.debouncedChange, e, 600);
}
}

async debouncedChange(e) {
await this.args.onChange(e);
this.isEditable = false;
}
}
48 changes: 32 additions & 16 deletions app/components/task-details.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,38 @@
<div class='task-details__title-container'>
<p class='task-details__title'>{{@task.title}}</p>
<div class='task-card__progress-bar-container'>
<div class='task-card__progress-bar-container__progress-bar'>
<Input
data-test-task-progress-bar
class='progress-bar__input {{@progressBarClass}}'
id='input'
type='range'
name='percentCompleted'
value={{@percentCompleted}}
min='0'
max='100'
step='10'
{{on 'change' @onPercentageChange}}
{{on 'change' (fn @onTaskUpdate @task.id)}}
disabled={{@isProgressBarDisabled}}
/>
{{@percentCompleted}}%
<div
class='{{unless
@dev
"task-card__progress-bar-container__progress-bar"
}}'
>
{{#if @dev}}
{{#if (eq @task.status 'IN_PROGRESS')}}
<ProgressBar
class='{{@progressBarClass}}'
@value={{@percentCompleted}}
@onChange={{@onPercentageChange}}
@onInput={{@onInputChange}}
/>
{{/if}}
{{else}}
<Input
data-test-task-progress-bar
class='progress-bar__input {{@progressBarClass}}'
id='input'
type='range'
name='percentCompleted'
value={{@percentCompleted}}
min='0'
max='100'
step='10'
{{on 'change' @onPercentageChange}}
disabled={{@isProgressBarDisabled}}
/>
{{@percentCompleted}}%
{{/if}}

</div>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions app/components/task/holder.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
@percentCompleted={{this.percentCompleted}}
@progressBarClass={{this.progressBarClass}}
@isProgressBarDisabled={{this.isProgressBarDisabled}}
@onInputChange={{this.progressBarInputChange}}
@dev={{@dev}}
/>

<div class='task-card__status-update-container'>
Expand Down
7 changes: 6 additions & 1 deletion app/components/task/holder.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,23 @@ export default class TasksHolderComponent extends Component {
return 'progress-bar-yellow';
}

@action progressBarInputChange(value) {
this.percentCompleted = value;
}

get isProgressBarDisabled() {
return this.args.task.status !== TASK_KEYS.IN_PROGRESS;
}

@action
onPercentageChange(e) {
async onPercentageChange(e) {
const { value } = e.target;
this.percentCompleted = value;
this.args.onTaskChange('percentCompleted', value);
if (value === TASK_PERCENTAGE.completedPercentage) {
this.percentCompleted = this.args.task.percentCompleted;
}
await this.onUpdate(this.args.task.id);
}

@action
Expand Down
1 change: 1 addition & 0 deletions app/components/tasks.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
@onTaskUpdate={{@onTaskUpdate}}
@userSelectedTask={{@userSelectedTask}}
@disabled={{@disabled}}
@dev={{@dev}}
/>
</div>
{{/each}}
Expand Down
7 changes: 7 additions & 0 deletions app/modifiers/focus-when.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { modifier } from 'ember-modifier';

export default modifier(function focusWhen(element, [isFocused]) {
Ajeyakrishna-k marked this conversation as resolved.
Show resolved Hide resolved
yesyash marked this conversation as resolved.
Show resolved Hide resolved
if (isFocused) {
element.focus();
}
});
1 change: 1 addition & 0 deletions app/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
@import 'card.css';
@import 'discord.css';
@import 'qrcode.css';
@import 'progress-bar.css';

html,
body {
Expand Down
81 changes: 81 additions & 0 deletions app/styles/progress-bar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
:root {
--progress-bar-color: rgba(0, 128, 0, 0.9);
--light-grey: rgba(128, 128, 128, 0.5);
--black: black;
--white: white;
}
.progress-slider {
display: flex;
gap: 4px;
}

.progress-slider__button {
width: 1.5rem;
height: 1.1rem;
border: 2px solid var(--black);
border-radius: 4px;
background-color: transparent;
display: flex;
align-items: center;
justify-items: center;
}

.progress-slider__button__text {
font-size: 0.6em;
font-weight: bolder;
margin: auto;
}

.progress-slider__button__edit-icon {
width: 1rem;
height: 1rem;
margin: 3px;
}
.progress-slider__input-slider {
-webkit-appearance: none;
appearance: none;
width: 90%;
height: 1.1rem;
cursor: pointer;
outline: none;
overflow: hidden;
border: 2px solid var(--black);
border-radius: 4px;
}

.progress-slider__input-slider:focus {
box-shadow: 0 0 0 2px var(--progress-bar-color);
}
.progress-slider__input-slider:disabled {
cursor: auto;
}

.progress-slider__input-slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 0;
box-shadow: -20rem 0 0 20rem var(--progress-bar-color);
}

.progress-slider__input-slider::-moz-range-thumb {
border: none;
width: 0;
box-shadow: -20rem 0 0 20rem var(--progress-bar-color);
}

.progress-slider__input-slider[step] {
background-color: transparent;
background: repeating-linear-gradient(
to right,
var(--white),
var(--white) calc(10.05% - 1.5px),
var(--black) 10.05%
);
}

.progress-slider__button--hover:hover {
background-color: var(--light-grey);
}

.progress-slider__button__edit-icon__inner {
fill: var(--progress-bar-color);
}
13 changes: 7 additions & 6 deletions app/styles/tasks.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@
}

.progress-bar-red {
--progress-bar-color: red;
--progress-bar-color:rgba(255, 0, 0, 0.8);
}
.progress-bar-yellow {
--progress-bar-color: #ecef08;
--progress-bar-color: rgba(255, 255, 0, 0.9);
}

.progress-bar-green {
--progress-bar-color: green;
--progress-bar-color: rgba(0, 128, 0, 0.9);
}
.progress-bar-orange {
--progress-bar-color: orange;
--progress-bar-color: rgba(255, 165, 0,0.9);
}

.tasks-page {
Expand Down Expand Up @@ -83,8 +83,9 @@
}

.task-card__progress-bar-container {
padding: 1em;
width: 15rem;
padding-right: 0.5em;
padding-bottom: 0.5em;
width: 14.5rem;
flex-shrink: 0;
}

Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
"dotenv": "^16.0.1",
"ember-cli-qrcode": "^2.1.0",
"ember-click-outside": "^5.0.1",
"ember-resources": "^5.6.0",
"mixpanel-browser": "^2.43.0",
"webpack": "^5.74.0",
"webpack-5": "^0.0.0",
"ember-resources": "^5.6.0"
"webpack-5": "^0.0.0"
},
"devDependencies": {
"@ember/jquery": "^2.0.0",
Expand All @@ -57,12 +57,14 @@
"ember-cli-dependency-checker": "^3.2.0",
"ember-cli-htmlbars": "^5.3.2",
"ember-cli-inject-live-reload": "^2.0.2",
"ember-cli-mirage": "^2.4.0",
"ember-cli-sri": "^2.1.1",
"ember-cli-terser": "^4.0.1",
"ember-data": "~3.25.0",
"ember-export-application-global": "^2.0.1",
"ember-load-initializers": "^2.1.2",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-modifier": "^4.1.0",
"ember-page-title": "^6.2.1",
"ember-qunit": "^5.1.3",
"ember-resolver": "^8.0.2",
Expand All @@ -85,7 +87,6 @@
"qunit": "^2.14.0",
"qunit-dom": "^1.6.0",
"toastr": "^2.1.4",
"ember-cli-mirage": "^2.4.0",
"tracked-maps-and-sets": "^3.0.2"
},
"engines": {
Expand Down
Loading
Loading