feat: add ProgressBar component #3321

Merged
konrad merged 4 commits from dpschen/frontend:add-progressbar-component into main 2024-02-07 10:53:49 +00:00
9 changed files with 179 additions and 55 deletions

View File

@ -0,0 +1,15 @@
<script setup lang="ts">
import {ref} from 'vue'
import ProgressBar from './ProgressBar.vue'
const value = ref(50)
</script>
<template>
<Story>
<Variant title="Default">
<ProgressBar :value="value" />
</Variant>
</Story>
</template>

View File

@ -0,0 +1,139 @@
<template>
<progress
class="progress-bar"
:class="{
'is-small': isSmall,
'is-primary': isPrimary,
}"
:value="value"
max="100"
>
{{ value }}%
</progress>
</template>
<script setup lang="ts">
import {defineProps} from 'vue'
defineProps({
value: {
type: Number,
required: true,
},
isSmall: {
type: Boolean,
default: false,
},
isPrimary: {
type: Boolean,
required: false,
},
})
</script>
<style lang="scss" scoped>
.progress-bar {
--progress-height: #{$size-normal};
--progress-bar-background-color: var(--border-light, #{$border-light});
--progress-value-background-color: var(--grey-500, #{$text});
--progress-border-radius: #{$radius};
--progress-indeterminate-duration: 1.5s;
appearance: none;
border: none;
border-radius: var(--progress-border-radius);
height: var(--progress-height);
overflow: hidden;
padding: 0;
min-width: 6vw;
width: 50px;
margin: 0 .5rem 0 0;
flex: 3 1 auto;
&::-moz-progress-bar,
&::-webkit-progress-value {
background: var(--progress-value-background-color);
}
@media screen and (max-width: $tablet) {
margin: 0.5rem 0 0 0;
order: 1;
width: 100%;
}
&::-webkit-progress-bar {
background-color: var(--progress-bar-background-color);
}
&::-webkit-progress-value {
background-color: var(--progress-value-background-color);
}
&::-moz-progress-bar {
konrad marked this conversation as resolved Outdated

Why the different rules instead of something like

&::-webkit-progress-value,
&::-moz-progress-bar,
&::-ms-fill {
	--progress-value-background-color: var(--#{$name}, #{$color}); 
}
Why the different rules instead of something like ``` &::-webkit-progress-value, &::-moz-progress-bar, &::-ms-fill { --progress-value-background-color: var(--#{$name}, #{$color}); } ```

This would be dropped by some browsers because prefixed selectors need individual rules, because invalid rules might make the whole selector invalid.

This would be dropped by some browsers because prefixed selectors need individual rules, because invalid rules might make the whole selector invalid.

yeah okay that makes sense

yeah okay that makes sense
background-color: var(--progress-value-background-color);
}
&::-ms-fill {
background-color: var(--progress-value-background-color);
border: none;
}
// Colors
@each $name, $pair in $colors {
$color: nth($pair, 1);
&.is-#{$name} {
--progress-value-background-color: var(--#{$name}, #{$color});
&:indeterminate {
background-image: linear-gradient(
to right,
var(--#{$name}, #{$color}) 30%,
var(--progress-bar-background-color) 30%
);
}
}
}
&:indeterminate {
animation-duration: var(--progress-indeterminate-duration);
animation-iteration-count: infinite;
animation-name: moveIndeterminate;
animation-timing-function: linear;
background-color: var(--progress-bar-background-color);
background-image: linear-gradient(
to right,
var(--text, #{$text}) 30%,
var(--progress-bar-background-color) 30%
);
background-position: top left;
background-repeat: no-repeat;
background-size: 150% 150%;
&::-webkit-progress-bar {
background-color: transparent;
}
&::-moz-progress-bar {
background-color: transparent;
}
&::-ms-fill {
animation-name: none;
}
}
&.is-small {
--progress-height: #{$size-small};
}
}
@keyframes moveIndeterminate {
from {
background-position: 200% 0;
}
to {
background-position: -200% 0;
}
}
</style>

View File

@ -16,14 +16,12 @@
ref="filesRef"
type="file"
/>
<progress
<ProgressBar
v-if="attachmentService.uploadProgress > 0"
:value="attachmentService.uploadProgress"
class="progress is-primary"
max="100"
>
{{ attachmentService.uploadProgress }}%
</progress>
:value="attachmentService.uploadProgress * 100"
is-primary
/>
<div class="files" v-if="attachments.length > 0">
<!-- FIXME: don't use a for element that wraps other links / buttons
@ -163,6 +161,7 @@ import {ref, shallowReactive, computed} from 'vue'
import {useDropZone} from '@vueuse/core'
import User from '@/components/misc/user.vue'
import ProgressBar from '@/components/misc/ProgressBar.vue'
import BaseButton from '@/components/base/BaseButton.vue'
import AttachmentService from '@/services/attachment'

View File

@ -41,12 +41,13 @@
</time>
</span>
<h3>{{ task.title }}</h3>
<progress
class="progress is-small"
<ProgressBar
class="task-progress"
v-if="task.percentDone > 0"
:value="task.percentDone * 100" max="100">
{{ task.percentDone * 100 }}%
</progress>
:value="task.percentDone * 100"
/>
<div class="footer">
<labels :labels="task.labels"/>
<priority-label
@ -79,6 +80,7 @@ import {ref, computed, watch} from 'vue'
import {useRouter} from 'vue-router'
import PriorityLabel from '@/components/tasks/partials/priorityLabel.vue'
import ProgressBar from '@/components/misc/ProgressBar.vue'
import Done from '@/components/misc/Done.vue'
import Labels from '@/components/tasks/partials/labels.vue'
import ChecklistSummary from './checklist-summary.vue'
@ -187,11 +189,6 @@ $task-background: var(--white);
word-break: break-word;
}
.progress {
margin: 8px 0 0 0;
width: 100%;
height: 0.5rem;
}
.due-date {
float: right;
@ -331,4 +328,10 @@ $task-background: var(--white);
.kanban-card__done {
margin-right: .25rem;
}
.task-progress {
margin: 8px 0 0 0;
width: 100%;
height: 0.5rem;
}
</style>

View File

@ -104,13 +104,11 @@
<checklist-summary :task="task"/>
</div>
<progress
class="progress is-small"
<ProgressBar
v-if="task.percentDone > 0"
:value="task.percentDone * 100" max="100"
>
{{ task.percentDone * 100 }}%
</progress>
:value="task.percentDone * 100"
is-small
/>
<ColorBubble
v-if="showProjectSeparately && projectColor !== '' && currentProject?.id !== task.projectId"
@ -166,6 +164,7 @@ import Labels from '@/components/tasks/partials//labels.vue'
import DeferTask from '@/components/tasks/partials//defer-task.vue'
import ChecklistSummary from '@/components/tasks/partials/checklist-summary.vue'
import ProgressBar from '@/components/misc/ProgressBar.vue'
import BaseButton from '@/components/base/BaseButton.vue'
import Fancycheckbox from '@/components/input/fancycheckbox.vue'
import ColorBubble from '@/components/misc/colorBubble.vue'
@ -495,10 +494,6 @@ function focusTaskLink() {
border-left-color: var(--grey-300);
border-bottom-color: var(--grey-300);
}
.progress {
margin-bottom: 0;
}
}
.subtask-nested {

View File

@ -182,9 +182,5 @@ const project = computed(() => projectStore.projects[task.projectId])
color: var(--grey-500);
width: auto;
}
.progress {
margin-bottom: 0;
}
}
</style>

View File

@ -15,11 +15,6 @@
}
}
.progress {
// overwrite bulma
margin-bottom: 0;
}
&.noborder {
margin: 1rem -0.5rem;
}

View File

@ -24,7 +24,7 @@
@import "bulma-css-variables/sass/elements/icon";
@import "bulma-css-variables/sass/elements/image";
//@import "bulma-css-variables/sass/elements/notification"; // not used
@import "bulma-css-variables/sass/elements/progress";
// @import "bulma-css-variables/sass/elements/progress"; // not used
@import "bulma-css-variables/sass/elements/table";
@import "bulma-css-variables/sass/elements/tag";
@import "bulma-css-variables/sass/elements/title";

View File

@ -42,23 +42,6 @@ h6 {
font-weight: 400 !important;
}
// FIXME: create <ProgressBar> component. used in
// - attachments.vue
// - kanban-card.vue
// - singleTaskInProject.vue
.progress {
border-radius: $radius-large;
width: 50px;
margin: 0 0.5rem 0 0;
flex: 3 1 auto;
@media screen and (max-width: $tablet) {
margin: 0.5rem 0 0 0;
order: 1;
width: 100%;
}
}
// FIXME: these helpers should be mixins
.has-no-border {
border: none !important;
@ -107,7 +90,6 @@ button.table {
.color-bubble {
display: inline-block;
border-radius: 100%;
margin-right: 4px;

Isn't this still used?

Isn't this still used?

Yes. Right now. Will remove here and instead move to follow up pr

Yes. Right now. Will remove here and instead move to follow up pr
}
.is-strikethrough {