Skip to content

Commit

Permalink
Merge pull request #28 from bcc-code/feature/ui-improvements
Browse files Browse the repository at this point in the history
feat(bmm-upload): improved ui
  • Loading branch information
KillerX authored Sep 17, 2024
2 parents 230a1de + 7f3127f commit 0964840
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 111 deletions.
21 changes: 14 additions & 7 deletions frontend/components/FileUploader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { FileAndLanguage } from "~/utils/bmm";
const props = defineProps<{
endpoint: string;
files: FileAndLanguage[];
metadata: { [key: string]: readonly string[] };
}>();
Expand All @@ -17,9 +16,17 @@ const uploadPercentageFiles = ref<{ [key: string]: number }>({});
const uploading = ref(false);
const uploadPercentage = ref(0);
watch(uploadPercentageFiles, () => {
uploadPercentage.value = Object.values(uploadPercentageFiles.value).reduce((a, b) => a + b, 0) / Object.keys(uploadPercentageFiles.value).length;
}, {deep: true});
watch(
uploadPercentageFiles,
() => {
uploadPercentage.value =
Object.values(uploadPercentageFiles.value).reduce(
(a, b) => a + b,
0,
) / Object.keys(uploadPercentageFiles.value).length;
},
{ deep: true },
);
watch(selectedFiles, () => {
uploadPercentage.value = 0;
Expand All @@ -31,7 +38,6 @@ const abort = ref<() => void>();
const uploadFile = () => {
for (const selectedFile of selectedFiles.value || []) {
if (!selectedFile.file) return;
uploading.value = true;
Expand All @@ -50,7 +56,8 @@ const uploadFile = () => {
xhr.open("post", props.endpoint, true);
xhr.upload.onprogress = function (ev) {
// Upload progress here
uploadPercentageFiles.value[selectedFile.file.name] = Math.floor((ev.loaded / ev.total) * 1000) / 10;
uploadPercentageFiles.value[selectedFile.file.name] =
Math.floor((ev.loaded / ev.total) * 1000) / 10;
};
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
Expand Down Expand Up @@ -95,7 +102,7 @@ const uploadFile = () => {
></div>
</div>
<span
class="m-auto bg-slate-600 px-2 py-1 font-bold text-white"
class="m-auto bg-neutral-600 px-2 py-1 font-bold text-white"
:class="
uploadPercentage !== 100 ? 'rounded-lg' : 'rounded-r-lg'
"
Expand Down
20 changes: 11 additions & 9 deletions frontend/components/LanguageSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ watch(
} else {
bmmLanguages.value = (
await api.getLanguages({ environment: newEnv })
).Languages;
).Languages.map((l) => l.code);
}
if (bmmLanguages.value.length == 1) {
Expand All @@ -33,14 +33,14 @@ watch(
const languageDisplay = (l: string) => {
if (typeof Intl.DisplayNames !== "undefined") {
const dn = new Intl.DisplayNames(["en"], { type: "language" });
let name = dn.of(l);
let name = dn.of(l);
// Chrome doesn't support "kha"
if (name == "kha") {
return "Khasi";
} else if (name == "zxx") {
return "Instrumental";
}
// Chrome doesn't support "kha"
if (name == "kha") {
return "Khasi";
} else if (name == "zxx") {
return "Instrumental";
}
return dn.of(l);
}
Expand All @@ -49,7 +49,9 @@ const languageDisplay = (l: string) => {

<template>
<BccSelect required v-model="model" :label="$t('language')">
<option v-if="bmmLanguages.length > 1" disabled value="">{{ $t("selectAnOption") }}</option>
<option v-if="bmmLanguages.length > 1" disabled value="">
{{ $t("selectAnOption") }}
</option>
<option v-for="l in bmmLanguages" :value="l">
{{ languageDisplay(l) }}
</option>
Expand Down
3 changes: 2 additions & 1 deletion frontend/components/PermissionView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const api = useAPI();
const availableLanguages = ref<string[]>([]);
api.getLanguages({ environment: BmmEnvironment.Production }).then(
(result) => (availableLanguages.value = result.Languages.map((f) => f.code)),
(result) =>
(availableLanguages.value = result.Languages.map((f) => f.code)),
);
watch(perms, () => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/SegmentEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const { deleteMode } = useDeleteMode();
<div
class="flex flex-col px-4"
:class="{
'cursor-pointer transition hover:bg-slate-800': deleteMode,
'cursor-pointer transition hover:bg-neutral-800': deleteMode,
}"
@click="deleteMode ? $emit('toggleDelete') : undefined"
>
Expand All @@ -61,7 +61,7 @@ const { deleteMode } = useDeleteMode();
contenteditable
v-for="(w, index) in segment.words"
@input="handleTextUpdate(index, $event)"
class="rounded-lg p-1 transition duration-75 focus:bg-slate-800 focus:outline-none"
class="rounded-lg p-1 transition duration-75 focus:bg-neutral-800 focus:outline-none"
@focus="$emit('wordFocus', w)"
>
{{ w.text }}
Expand Down
7 changes: 3 additions & 4 deletions frontend/components/SelectFile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ const handleDrop = (event: DragEvent) => {
const fileInput = ref<HTMLInputElement>(null!);
const selectFile = ( event: Event ) => {
const selectFile = (event: Event) => {
const target = event.target as HTMLInputElement;
for (const file of target.files??[]) {
for (const file of target.files ?? []) {
selectedFiles.value.push({
file: file as File,
language: props.defaultLanguage,
Expand All @@ -47,12 +47,11 @@ const props = defineProps<{
defaultLanguage: string;
acceptMultiple: boolean;
}>();
</script>

<template>
<div
class="bg-gray mx-auto flex h-48 w-full cursor-pointer rounded-lg border-2 bg-slate-800 text-center text-white transition hover:bg-slate-700"
class="mx-auto flex h-48 w-full cursor-pointer rounded-lg border border-neutral-300 bg-neutral-100 text-center text-primary transition hover:bg-neutral-200"
@click="fileInput?.click()"
:class="[isDragOver ? 'border-green-500' : 'border-slate-700']"
@dragenter.prevent="dragEnter"
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/TranscriptionEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const segmentelements = defineModel<{

<template>
<div class="flex flex-col overflow-auto bg-black text-xl">
<div class="flex gap-4 bg-slate-800 p-4">
<div class="flex gap-4 bg-neutral-800 p-4">
<slot name="actions"></slot>
<BccButton
class="ml-auto"
Expand Down
28 changes: 13 additions & 15 deletions frontend/components/bmm/BmmSingleMetadata.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { BccAlert, BccButton, BccInput, BccSelect } from "@bcc-code/design-library-vue";
import { BmmEnvironment, BMMPermission, BMMTrack } from "~/src/gen/api/v1/api_pb";
import { BccButton, BccSelect } from "@bcc-code/design-library-vue";
import { BmmEnvironment, BMMPermission } from "~/src/gen/api/v1/api_pb";
defineProps<{
permissions: BMMPermission;
Expand All @@ -10,9 +10,8 @@ defineProps<{
const form = defineModel<BMMSingleForm>({ required: true });
const albumId = computedProperty(form, "albumId");
const track = computedProperty<BMMTrack>(form, "track");
const track = computedProperty(form, "track");
const language = computedProperty(form, "language");
const title = computedProperty(form, "title");
const selectedEnvironment = computedProperty(form, "environment");
const emit = defineEmits<{
Expand All @@ -22,15 +21,15 @@ const emit = defineEmits<{
function checkForm() {
if (!track.value) {
alert("Please select a track");
return
return;
}
emit('set')
emit("set");
}
</script>
<template>
<form class="flex flex-col gap-4 p-4" @submit.prevent="checkForm">
<h3 class="text-lg font-bold">BMM Upload</h3>
<h3 class="text-heading-xl">BMM Upload</h3>

<BccSelect
v-if="permissions.integration"
Expand All @@ -54,13 +53,12 @@ function checkForm() {
:album="albumId"
:env="environment"
/>
<div class="flex flex-col gap-2 border-2 border-slate-950 p-4">
<LanguageSelector
v-model="language"
:languages="permissions.languages"
:env="environment"
/>
</div>
<BccButton type="submit" >{{ $t("next") }}</BccButton>
<LanguageSelector
v-model="language"
:languages="permissions.languages"
:env="environment"
/>

<BccButton type="submit" class="mt-4">{{ $t("next") }}</BccButton>
</form>
</template>
63 changes: 44 additions & 19 deletions frontend/components/bmm/BmmTrackSelector.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<script lang="ts" setup>
import { BccFormLabel } from "@bcc-code/design-library-vue";
import {
BccButton,
BccFormLabel,
BccTable,
BccSpinner,
} from "@bcc-code/design-library-vue";
import { BmmEnvironment, BMMTrack } from "~/src/gen/api/v1/api_pb";
const tracks = ref<BMMTrack[]>();
Expand Down Expand Up @@ -36,33 +41,53 @@ watch(
);
const selectedTrack = defineModel<BMMTrack>();
function onTrackClick(track: BMMTrack) {
if (selectedTrack.value && selectedTrack.value.id == track.id) {
selectedTrack.value = undefined;
} else {
selectedTrack.value = track;
}
}
const filteredTracks = computed(() => {
if (!tracks.value?.length) return [];
if (!selectedTrack.value) {
return tracks.value;
}
return tracks.value.filter((t) => t.id == selectedTrack.value!.id);
});
</script>

<template>
<div>
<div class="h-96 overflow-y-auto">
<BccFormLabel>
{{ label }}
</BccFormLabel>
<div v-if="selectedTrack" class="flex">
<BmmTrackView
@click="selectedTrackId = ''"
v-if="selectedTrack"
:track="selectedTrack"
/>
</div>
<div
v-else-if="tracks && tracks.length > 0"
class="flex h-48 flex-col gap-2 overflow-y-auto"
v-if="tracks && tracks.length > 0"
class="relative mt-2 gap-2 space-y-2"
>
<div v-for="t in tracks" class="flex">
<BmmTrackView :track="t" @click="selectedTrack = t" />
</div>
<TransitionGroup
move-class="transition duration-600 ease-out"
enter-active-class="transition duration-600 ease-out"
enter-from-class="opacity-0 scale-95"
enter-to-class="opacity-100 scale-100"
leave-active-class="transition duration-600 ease-out absolute"
leave-from-class="opacity-100 scale-100"
leave-to-class="opacity-0 scale-95"
>
<BmmTrackView
v-for="t in filteredTracks"
:key="t.id"
:track="t"
@click="onTrackClick(t)"
/>
</TransitionGroup>
</div>

<div v-else>
<p class="flex cursor-pointer gap-2 rounded bg-slate-50">
<span class="rounded bg-slate-200 px-2">Loading</span>
</p>
</div>
<BccSpinner v-else size="sm" class="mx-auto" />
</div>
</template>
25 changes: 20 additions & 5 deletions frontend/components/bmm/BmmTrackView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,26 @@ const dateString = (date: Date) => {
</script>

<template>
<div class="flex w-full cursor-pointer gap-2 rounded bg-slate-200 pl-2">
<span v-if="track && track.publishedAt">
{{ dateString(track.publishedAt.toDate()) }}</span
<div
class="flex w-full cursor-pointer items-center overflow-clip rounded-md border border-on-primary bg-primary shadow-sm hover:border-neutral-300"
>
<span
v-if="track && track.publishedAt"
class="w-24 bg-secondary px-2 py-1 text-left text-secondary"
>
<span class="bg-slate-50 px-2 flex-grow">{{ track.title }}</span>
<span class="rounded-r text-lg pr-2"><img v-for="l in track.languages?.Languages" :title="l.code" :src="'/images/flags/'+l.code+'.svg'" class="h-4 inline pl-1" :alt="l.code"/></span>
{{ dateString(track.publishedAt.toDate()) }}
</span>
<span class="grow px-2 py-1 text-primary">
{{ track.title }}
</span>
<span class="flex h-full gap-1 bg-secondary px-2 py-2">
<img
v-for="l in track.languages?.Languages"
:title="l.code"
:src="'/images/flags/' + l.code + '.svg'"
class="inline h-4 rounded-sm border border-white shadow-sm"
:alt="l.code"
/>
</span>
</div>
</template>
2 changes: 1 addition & 1 deletion frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default defineNuxtConfig({
app: {
head: {
bodyAttrs: {
class: "bg-slate-900 md:bg-slate-800 text-white",
class: "bg-neutral-100",
},
},
pageTransition: { name: "page", mode: "out-in" },
Expand Down
2 changes: 1 addition & 1 deletion frontend/pages/admin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const removeEmail = async (email: string) => {
<template>
<div class="flex h-screen w-screen" v-if="me?.admin">
<div
class="mx-auto w-full max-w-screen-md rounded-lg border-2 border-slate-950 bg-zinc-100 p-8 text-black"
class="mx-auto w-full max-w-screen-md rounded-lg border-2 border-neutral-950 bg-zinc-100 p-8 text-black"
>
<h3 class="text-lg">Admin</h3>
<div class="flex flex-col gap-4" v-if="permissions">
Expand Down
24 changes: 17 additions & 7 deletions frontend/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
<script setup lang="ts">
import { BccItemTile, BccLinkItem } from "@bcc-code/design-library-vue";
</script>

<template>
<div class="flex flex-col gap-4">
<NuxtLink to="/upload/bmm/" class="rounded bg-slate-700 p-2"
>BMM Upload</NuxtLink
>
<NuxtLink to="/transcription/" class="rounded bg-slate-700 p-2"
>Transcription</NuxtLink
>
<div class="grid grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-4 p-8">
<NuxtLink to="/upload/bmm/">
<BccItemTile
title="BMM Upload"
class="border-on-secondary bg-white"
/>
</NuxtLink>
<NuxtLink to="/transcription">
<BccItemTile
title="Transcription"
class="border-on-secondary bg-white"
/>
</NuxtLink>
</div>
</template>
2 changes: 1 addition & 1 deletion frontend/pages/transcription/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const seekOnFocus = computed({
</script>

<template>
<div class="flex h-screen divide-x-2 divide-slate-500">
<div class="flex h-screen divide-x-2 divide-neutral-500">
<div class="flex w-1/2 flex-col">
<div v-if="loading" class="mx-auto animate-ping">Loading...</div>
<TranscriptionEditor
Expand Down
Loading

0 comments on commit 0964840

Please sign in to comment.