web/satellite: updated styling of Upload hover component
Added box shadow and added icons for each object type. Issue: https://github.com/storj/storj/issues/5974 Change-Id: I5dd7c7cd5e0066d4da75f655feb162abad7bec3b
This commit is contained in:
parent
cb9a7bdc71
commit
fe0c3a13b4
@ -124,6 +124,7 @@ import { BrowserObject, useObjectBrowserStore } from '@/store/modules/objectBrow
|
|||||||
import { useAppStore } from '@/store/modules/appStore';
|
import { useAppStore } from '@/store/modules/appStore';
|
||||||
import { useConfigStore } from '@/store/modules/configStore';
|
import { useConfigStore } from '@/store/modules/configStore';
|
||||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||||
|
import { ObjectType } from '@/utils/objectIcon';
|
||||||
|
|
||||||
import TableItem from '@/components/common/TableItem.vue';
|
import TableItem from '@/components/common/TableItem.vue';
|
||||||
|
|
||||||
@ -154,32 +155,7 @@ const deleteConfirmation = ref(false);
|
|||||||
/**
|
/**
|
||||||
* Return the type of the file.
|
* Return the type of the file.
|
||||||
*/
|
*/
|
||||||
const fileType = computed((): string => {
|
const fileType = computed((): string => ObjectType.findType(props.file.Key));
|
||||||
const image = /(\.jpg|\.jpeg|\.png|\.gif)$/i;
|
|
||||||
const video = /(\.mp4|\.mkv|\.mov)$/i;
|
|
||||||
const audio = /(\.mp3|\.aac|\.wav|\.m4a)$/i;
|
|
||||||
const text = /(\.txt|\.docx|\.doc|\.pages)$/i;
|
|
||||||
const pdf = /(\.pdf)$/i;
|
|
||||||
const archive = /(\.zip|\.tar.gz|\.7z|\.rar)$/i;
|
|
||||||
const spreadsheet = /(\.xls|\.numbers|\.csv|\.xlsx|\.tsv)$/i;
|
|
||||||
|
|
||||||
if (image.exec(props.file.Key)) {
|
|
||||||
return 'image';
|
|
||||||
} else if (video.exec(props.file.Key)) {
|
|
||||||
return 'video';
|
|
||||||
} else if (audio.exec(props.file.Key)) {
|
|
||||||
return 'audio';
|
|
||||||
} else if (text.exec(props.file.Key)) {
|
|
||||||
return 'text';
|
|
||||||
} else if (pdf.exec(props.file.Key)) {
|
|
||||||
return 'pdf';
|
|
||||||
} else if (archive.exec(props.file.Key)) {
|
|
||||||
return 'archive';
|
|
||||||
} else if (spreadsheet.exec(props.file.Key)) {
|
|
||||||
return 'spreadsheet';
|
|
||||||
}
|
|
||||||
return 'file';
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the size of the file formatted.
|
* Return the size of the file formatted.
|
||||||
|
@ -44,26 +44,13 @@
|
|||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { ProjectRole } from '@/types/projectMembers';
|
import { ProjectRole } from '@/types/projectMembers';
|
||||||
|
import { ObjectType } from '@/utils/objectIcon';
|
||||||
|
|
||||||
import VTableCheckbox from '@/components/common/VTableCheckbox.vue';
|
import VTableCheckbox from '@/components/common/VTableCheckbox.vue';
|
||||||
import BucketGuide from '@/components/objects/BucketGuide.vue';
|
import BucketGuide from '@/components/objects/BucketGuide.vue';
|
||||||
import MiddleTruncate from '@/components/browser/MiddleTruncate.vue';
|
import MiddleTruncate from '@/components/browser/MiddleTruncate.vue';
|
||||||
import ProjectOwnershipTag from '@/components/project/ProjectOwnershipTag.vue';
|
import ProjectOwnershipTag from '@/components/project/ProjectOwnershipTag.vue';
|
||||||
|
|
||||||
import TableLockedIcon from '@/../static/images/browser/tableLocked.svg';
|
|
||||||
import ColorFolderIcon from '@/../static/images/objects/colorFolder.svg';
|
|
||||||
import ColorBucketIcon from '@/../static/images/objects/colorBucket.svg';
|
|
||||||
import FileIcon from '@/../static/images/objects/file.svg';
|
|
||||||
import AudioIcon from '@/../static/images/objects/audio.svg';
|
|
||||||
import VideoIcon from '@/../static/images/objects/video.svg';
|
|
||||||
import ChevronLeftIcon from '@/../static/images/objects/chevronLeft.svg';
|
|
||||||
import GraphIcon from '@/../static/images/objects/graph.svg';
|
|
||||||
import PdfIcon from '@/../static/images/objects/pdf.svg';
|
|
||||||
import PictureIcon from '@/../static/images/objects/picture.svg';
|
|
||||||
import TxtIcon from '@/../static/images/objects/txt.svg';
|
|
||||||
import ZipIcon from '@/../static/images/objects/zip.svg';
|
|
||||||
import ProjectIcon from '@/../static/images/navigation/project.svg';
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
selectDisabled?: boolean;
|
selectDisabled?: boolean;
|
||||||
selectHidden?: boolean;
|
selectHidden?: boolean;
|
||||||
@ -91,23 +78,7 @@ const props = withDefaults(defineProps<{
|
|||||||
|
|
||||||
const emit = defineEmits(['selectClicked']);
|
const emit = defineEmits(['selectClicked']);
|
||||||
|
|
||||||
const icons = new Map<string, string>([
|
const icon = computed((): string => ObjectType.findIcon(props.itemType));
|
||||||
['locked', TableLockedIcon],
|
|
||||||
['bucket', ColorBucketIcon],
|
|
||||||
['folder', ColorFolderIcon],
|
|
||||||
['file', FileIcon],
|
|
||||||
['audio', AudioIcon],
|
|
||||||
['video', VideoIcon],
|
|
||||||
['back', ChevronLeftIcon],
|
|
||||||
['spreadsheet', GraphIcon],
|
|
||||||
['pdf', PdfIcon],
|
|
||||||
['image', PictureIcon],
|
|
||||||
['text', TxtIcon],
|
|
||||||
['archive', ZipIcon],
|
|
||||||
['project', ProjectIcon],
|
|
||||||
]);
|
|
||||||
|
|
||||||
const icon = computed(() => icons.get(props.itemType.toLowerCase()));
|
|
||||||
|
|
||||||
const customIconClasses = computed(() => {
|
const customIconClasses = computed(() => {
|
||||||
const classes = {};
|
const classes = {};
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
<div class="modal__header" :class="{'custom-radius': !isExpanded}" @click="toggleExpanded">
|
<div class="modal__header" :class="{'custom-radius': !isExpanded}" @click="toggleExpanded">
|
||||||
<div class="modal__header__left">
|
<div class="modal__header__left">
|
||||||
<div class="modal__header__left__info">
|
<div class="modal__header__left__info">
|
||||||
<p class="modal__header__left__info__title">{{ statusLabel }}</p>
|
<div class="modal__header__left__info__cont">
|
||||||
|
<CompleteIcon v-if="isClosable" />
|
||||||
|
<p class="modal__header__left__info__cont__title">{{ statusLabel }}</p>
|
||||||
|
</div>
|
||||||
<p class="modal__header__left__info__remaining">{{ remainingTimeString }}</p>
|
<p class="modal__header__left__info__remaining">{{ remainingTimeString }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!isClosable" class="modal__header__left__track">
|
<div v-if="!isClosable" class="modal__header__left__track">
|
||||||
@ -37,6 +40,7 @@ import UploadItem from '@/components/modals/objectUpload/UploadItem.vue';
|
|||||||
|
|
||||||
import ArrowIcon from '@/../static/images/modals/objectUpload/arrow.svg';
|
import ArrowIcon from '@/../static/images/modals/objectUpload/arrow.svg';
|
||||||
import CloseIcon from '@/../static/images/modals/objectUpload/close.svg';
|
import CloseIcon from '@/../static/images/modals/objectUpload/close.svg';
|
||||||
|
import CompleteIcon from '@/../static/images/modals/objectUpload/complete.svg';
|
||||||
|
|
||||||
const obStore = useObjectBrowserStore();
|
const obStore = useObjectBrowserStore();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
@ -187,6 +191,7 @@ onMounted(() => {
|
|||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-family: 'font_regular', sans-serif;
|
font-family: 'font_regular', sans-serif;
|
||||||
|
filter: drop-shadow(0 7px 20px rgb(0 0 0 / 15%));
|
||||||
|
|
||||||
@media screen and (width <= 650px) {
|
@media screen and (width <= 650px) {
|
||||||
max-width: unset;
|
max-width: unset;
|
||||||
@ -217,11 +222,20 @@ onMounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
&__title {
|
&__cont {
|
||||||
font-family: 'font_medium', sans-serif;
|
display: flex;
|
||||||
font-size: 14px;
|
align-items: center;
|
||||||
line-height: 20px;
|
|
||||||
color: var(--c-white);
|
svg {
|
||||||
|
margin-right: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
font-family: 'font_medium', sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: var(--c-white);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__remaining {
|
&__remaining {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="item__left">
|
<div class="item__left">
|
||||||
<div class="item__left__icon">
|
<div class="item__left__icon">
|
||||||
<p class="item__left__icon__label">{{ extension }}</p>
|
<component :is="icon" />
|
||||||
</div>
|
</div>
|
||||||
<p class="item__left__name" :title="item.Key">{{ item.Key }}</p>
|
<p class="item__left__name" :title="item.Key">{{ item.Key }}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -57,6 +57,7 @@ import {
|
|||||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||||
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
|
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
|
||||||
import { useNotify } from '@/utils/hooks';
|
import { useNotify } from '@/utils/hooks';
|
||||||
|
import { ObjectType } from '@/utils/objectIcon';
|
||||||
|
|
||||||
import VInfo from '@/components/common/VInfo.vue';
|
import VInfo from '@/components/common/VInfo.vue';
|
||||||
|
|
||||||
@ -75,11 +76,9 @@ const props = defineProps<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns file's extension.
|
* Returns appropriate icon for provided object.
|
||||||
*/
|
*/
|
||||||
const extension = computed((): string => {
|
const icon = computed((): string => ObjectType.findIcon(ObjectType.findType(props.item.Key)));
|
||||||
return props.item.Key.split('.').pop()?.substring(0, 3).toUpperCase() || 'EXT';
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns progress bar style.
|
* Returns progress bar style.
|
||||||
@ -144,7 +143,8 @@ function cancelUpload(): void {
|
|||||||
min-width: 32px;
|
min-width: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
background-color: var(--c-green-6);
|
background-color: var(--c-white);
|
||||||
|
border: 1px solid var(--c-grey-2);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -154,13 +154,6 @@ function cancelUpload(): void {
|
|||||||
@media screen and (width <= 550px) {
|
@media screen and (width <= 550px) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__label {
|
|
||||||
font-family: 'font_bold', sans-serif;
|
|
||||||
font-size: 9px;
|
|
||||||
line-height: 18px;
|
|
||||||
color: var(--c-green-5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__name {
|
&__name {
|
||||||
|
68
web/satellite/src/utils/objectIcon.ts
Normal file
68
web/satellite/src/utils/objectIcon.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (C) 2023 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
import TableLockedIcon from '@/../static/images/browser/tableLocked.svg';
|
||||||
|
import ColorBucketIcon from '@/../static/images/objects/colorBucket.svg';
|
||||||
|
import ColorFolderIcon from '@/../static/images/objects/colorFolder.svg';
|
||||||
|
import FileIcon from '@/../static/images/objects/file.svg';
|
||||||
|
import AudioIcon from '@/../static/images/objects/audio.svg';
|
||||||
|
import VideoIcon from '@/../static/images/objects/video.svg';
|
||||||
|
import ChevronLeftIcon from '@/../static/images/objects/chevronLeft.svg';
|
||||||
|
import GraphIcon from '@/../static/images/objects/graph.svg';
|
||||||
|
import PdfIcon from '@/../static/images/objects/pdf.svg';
|
||||||
|
import PictureIcon from '@/../static/images/objects/picture.svg';
|
||||||
|
import TxtIcon from '@/../static/images/objects/txt.svg';
|
||||||
|
import ZipIcon from '@/../static/images/objects/zip.svg';
|
||||||
|
import ProjectIcon from '@/../static/images/navigation/project.svg';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents functionality to find object's type and appropriate icon for this type.
|
||||||
|
*/
|
||||||
|
export class ObjectType {
|
||||||
|
private static icons = new Map<string, string>([
|
||||||
|
['locked', TableLockedIcon],
|
||||||
|
['bucket', ColorBucketIcon],
|
||||||
|
['folder', ColorFolderIcon],
|
||||||
|
['file', FileIcon],
|
||||||
|
['audio', AudioIcon],
|
||||||
|
['video', VideoIcon],
|
||||||
|
['back', ChevronLeftIcon],
|
||||||
|
['spreadsheet', GraphIcon],
|
||||||
|
['pdf', PdfIcon],
|
||||||
|
['image', PictureIcon],
|
||||||
|
['text', TxtIcon],
|
||||||
|
['archive', ZipIcon],
|
||||||
|
['project', ProjectIcon],
|
||||||
|
]);
|
||||||
|
|
||||||
|
static findIcon(type: string): string {
|
||||||
|
return this.icons.get(type.toLowerCase()) || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
static findType(object: string): string {
|
||||||
|
const image = /(\.jpg|\.jpeg|\.png|\.gif)$/i;
|
||||||
|
const video = /(\.mp4|\.mkv|\.mov)$/i;
|
||||||
|
const audio = /(\.mp3|\.aac|\.wav|\.m4a)$/i;
|
||||||
|
const text = /(\.txt|\.docx|\.doc|\.pages)$/i;
|
||||||
|
const pdf = /(\.pdf)$/i;
|
||||||
|
const archive = /(\.zip|\.tar.gz|\.7z|\.rar)$/i;
|
||||||
|
const spreadsheet = /(\.xls|\.numbers|\.csv|\.xlsx|\.tsv)$/i;
|
||||||
|
|
||||||
|
if (image.exec(object)) {
|
||||||
|
return 'image';
|
||||||
|
} else if (video.exec(object)) {
|
||||||
|
return 'video';
|
||||||
|
} else if (audio.exec(object)) {
|
||||||
|
return 'audio';
|
||||||
|
} else if (text.exec(object)) {
|
||||||
|
return 'text';
|
||||||
|
} else if (pdf.exec(object)) {
|
||||||
|
return 'pdf';
|
||||||
|
} else if (archive.exec(object)) {
|
||||||
|
return 'archive';
|
||||||
|
} else if (spreadsheet.exec(object)) {
|
||||||
|
return 'spreadsheet';
|
||||||
|
}
|
||||||
|
return 'file';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="24" height="24" rx="12" fill="#00AC26"/>
|
||||||
|
<path d="M17.1705 8.64013C17.469 8.952 17.4763 9.4529 17.1923 9.77398L17.1705 9.79772L11.2997 15.9299C11.1846 16.0501 11.0432 16.1267 10.8947 16.1595C10.6392 16.2487 10.3463 16.1924 10.1358 15.9867L10.1267 15.9776L6.8295 12.5338C6.52347 12.2142 6.52347 11.6959 6.8295 11.3762C7.12807 11.0644 7.60762 11.0568 7.91502 11.3534L7.93775 11.3762L10.6903 14.2512L16.0622 8.64013C16.3682 8.32048 16.8644 8.32048 17.1705 8.64013Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 602 B |
Loading…
Reference in New Issue
Block a user