Changeset 35901 for main/trunk/model-interfaces-dev
- Timestamp:
- 2022-01-07T15:06:35+13:00 (2 years ago)
- Location:
- main/trunk/model-interfaces-dev/atea/macron-restoration/src/components
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/model-interfaces-dev/atea/macron-restoration/src/components/DirectInput.vue
r35819 r35901 1 <template>2 <div class="root">3 <textarea class="text-input input-area" @input="onTextInput" autocomplete="off"4 v-model="input" :placeholder="translations.get('DirectInput_InputPlaceholder')" />5 6 <div class="text-container">7 <span v-if="errorState" class="material-icons mdi-m error-text">error</span>8 <span v-if="errorState" class="error-text">{{ translations.get('DirectInput_UnknownError') }}</span>9 10 <span class="preserveWhitespace" v-html="htmlFormattedRestored" />11 </div>12 13 <div class="flex">14 <input type="checkbox" id="i-preserve-existing-macrons" v-model="preserveExistingMacrons" @input="startMacronisationWait" />15 <label for="i-preserve-existing-macrons">{{ translations.get('DirectInput_PreserveExistingMacrons') }}</label>16 </div>17 18 <div class="flex">19 <input type="checkbox" id="i-show-macronised-words" v-model="showMacronisedWords" :disabled="restored.length === 0" />20 <label for="i-show-macronised-words">{{ translations.get('DirectInput_ShowMacronisedWords') }}</label>21 </div>22 23 <div class="flex right-column">24 <input type="checkbox" id="i-show-macronised-words" v-model="normaliseLinebreaks" :disabled="restored.length === 0" />25 <label for="i-show-macronised-words">{{ translations.get('DirectInput_NormaliseLinebreaks') }}</label>26 </div>27 28 <button class="btn-primary right-column" :disabled="!canDownload" @click="copyToClipboard">29 {{ translations.get('DirectInput_CopyToClipboard') }}30 </button>31 32 <button class="btn-primary right-column" :disabled="!canDownload" @click="downloadAsText">33 {{ translations.get('DirectInput_Download') }}34 </button>35 </div>36 </template>37 38 <style scoped lang="scss">39 .root {40 display: grid;41 grid-template-columns: 1fr 1fr;42 gap: 1em;43 }44 45 .preserveWhitespace {46 white-space: pre-line;47 }48 49 .input-area {50 resize: vertical;51 min-height: 4em;52 }53 54 .flex {55 display: flex;56 align-items: center;57 gap: 0.5em;58 }59 60 .right-column {61 grid-column: 2;62 }63 64 .highlight {65 background-color: var(--highlighted-word-bg);66 }67 68 .error-text {69 color: rgb(185, 3, 3);70 }71 </style>72 73 1 <script> 74 2 import { mapState } from "vuex"; … … 228 156 } 229 157 </script> 158 159 <template> 160 <div class="root"> 161 <textarea class="text-input input-area" @input="onTextInput" autocomplete="off" 162 v-model="input" :placeholder="translations.get('DirectInput_InputPlaceholder')" /> 163 164 <div class="text-container"> 165 <span v-if="errorState" class="material-icons mdi-m error-text">error</span> 166 <span v-if="errorState" class="error-text">{{ translations.get('DirectInput_UnknownError') }}</span> 167 168 <span class="preserveWhitespace" v-html="htmlFormattedRestored" /> 169 </div> 170 171 <div class="flex"> 172 <input type="checkbox" id="i-preserve-existing-macrons" v-model="preserveExistingMacrons" @input="startMacronisationWait" /> 173 <label for="i-preserve-existing-macrons">{{ translations.get('DirectInput_PreserveExistingMacrons') }}</label> 174 </div> 175 176 <div class="flex"> 177 <input type="checkbox" id="i-show-macronised-words" v-model="showMacronisedWords" :disabled="restored.length === 0" /> 178 <label for="i-show-macronised-words">{{ translations.get('DirectInput_ShowMacronisedWords') }}</label> 179 </div> 180 181 <div class="flex right-column"> 182 <input type="checkbox" id="i-show-macronised-words" v-model="normaliseLinebreaks" :disabled="restored.length === 0" /> 183 <label for="i-show-macronised-words">{{ translations.get('DirectInput_NormaliseLinebreaks') }}</label> 184 </div> 185 186 <button class="btn-primary right-column" :disabled="!canDownload" @click="copyToClipboard"> 187 {{ translations.get('DirectInput_CopyToClipboard') }} 188 </button> 189 190 <button class="btn-primary right-column" :disabled="!canDownload" @click="downloadAsText"> 191 {{ translations.get('DirectInput_Download') }} 192 </button> 193 </div> 194 </template> 195 196 <style scoped lang="scss"> 197 .root { 198 display: grid; 199 grid-template-columns: 1fr 1fr; 200 gap: 1em; 201 } 202 203 .preserveWhitespace { 204 white-space: pre-line; 205 } 206 207 .input-area { 208 resize: vertical; 209 min-height: 4em; 210 } 211 212 .flex { 213 display: flex; 214 align-items: center; 215 gap: 0.5em; 216 } 217 218 .right-column { 219 grid-column: 2; 220 } 221 222 .highlight { 223 background-color: var(--highlighted-word-bg); 224 } 225 226 .error-text { 227 color: rgb(185, 3, 3); 228 } 229 </style> -
main/trunk/model-interfaces-dev/atea/macron-restoration/src/components/FileUpload.vue
r35900 r35901 1 <template>2 <div class="audio-file-picker">3 <div class="input-bar">4 <div class="text-input-sl" style="cursor: pointer;" @click="openFilePicker">5 <span class="text-placeholder material-icons">attach_file</span>6 <span class="text-placeholder" v-if="!anyFiles">{{ translations.get("FileUpload_SelectFiles") }}</span>7 8 <div class="uploaded-file-listing" v-for="(file, index) in files" :key="file.name">9 <span>{{ file.name }}</span>10 <button type="button" @click="onFileRemove($event, index)" class="btn-pin">11 <span class="material-icons mdi-s">close</span>12 </button>13 </div>14 </div>15 16 <input ref="fileInput" type="file" @input="onFilesChanged"17 accept="application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.oasis.opendocument.text,text/plain,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"18 multiple :disabled="isMacronising" />19 20 <button class="btn-primary" type="submit" :disabled="!anyFiles || isMacronising" @click="doMacronisation">21 <span class="material-icons">history_edu</span>22 <span>{{ translations.get("FileUpload_MacroniseFiles") }}</span>23 </button>24 </div>25 26 <div v-if="isMacronising" class="progress-bar-container">27 <div class="progress-bar-value progress-bar-indeterminate" />28 </div>29 30 <ul class="list-view" v-if="failures.size > 0">31 <li v-for="[id, failure] in failures" :key="failure.id" class="list-view__item transcription-error-container">32 <div>33 {{ translations.get("FileUpload_MacronisationFailed-Message") }} <i v-if="failure.fileName">{{ failure.fileName }}</i><br />34 <span v-if="failure.message">{{ translations.get("FileUpload_MacronisationFailed-Reason") }}: {{ failure.message }}</span>35 </div>36 37 <button class="btn-fab theme-flat" @click="dismissFailure(id)">38 <span class="material-icons">clear</span>39 </button>40 </li>41 </ul>42 </div>43 </template>44 45 <style scoped lang="scss">46 .audio-file-picker {47 display: flex;48 gap: 0.5em;49 flex-direction: column;50 51 input {52 display: none;53 }54 55 .text-container {56 cursor: pointer;57 }58 }59 60 .input-bar {61 display: grid;62 align-items: stretch;63 gap: 0.5em;64 grid-template-columns: 1fr auto;65 }66 67 .uploaded-file-listing {68 display: flex;69 align-items: center;70 71 padding: 3px;72 gap: 5px;73 74 border: 1px solid var(--bg-color);75 border-radius: 3px;76 border-left: 4px solid var(--bg-color);77 background: rgba(var(--bg-color-raw), 0.1);78 79 margin-right: 0.5em;80 &:last-child {81 margin-right: 0;82 }83 }84 85 .transcription-error-container {86 display: grid;87 gap: 0.5em;88 grid-template-columns: 1fr auto;89 align-items: center;90 91 border-left: 3px solid red;92 }93 </style>94 95 1 <script> 96 2 import { mapState } from "vuex"; … … 236 142 } 237 143 </script> 144 145 <template> 146 <div class="audio-file-picker"> 147 <div class="input-bar"> 148 <div class="text-input-sl" style="cursor: pointer;" @click="openFilePicker"> 149 <span class="text-placeholder material-icons">attach_file</span> 150 <span class="text-placeholder" v-if="!anyFiles">{{ translations.get("FileUpload_SelectFiles") }}</span> 151 152 <div class="uploaded-file-listing" v-for="(file, index) in files" :key="file.name"> 153 <span>{{ file.name }}</span> 154 <button type="button" @click="onFileRemove($event, index)" class="btn-pin"> 155 <span class="material-icons mdi-s">close</span> 156 </button> 157 </div> 158 </div> 159 160 <input ref="fileInput" type="file" @input="onFilesChanged" 161 accept="application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.oasis.opendocument.text,text/plain,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 162 multiple :disabled="isMacronising" /> 163 164 <button class="btn-primary" type="submit" :disabled="!anyFiles || isMacronising" @click="doMacronisation"> 165 <span class="material-icons">history_edu</span> 166 <span>{{ translations.get("FileUpload_MacroniseFiles") }}</span> 167 </button> 168 </div> 169 170 <div v-if="isMacronising" class="progress-bar-container"> 171 <div class="progress-bar-value progress-bar-indeterminate" /> 172 </div> 173 174 <ul class="list-view" v-if="failures.size > 0"> 175 <li v-for="[id, failure] in failures" :key="failure.id" class="list-view__item transcription-error-container"> 176 <div> 177 {{ translations.get("FileUpload_MacronisationFailed-Message") }} <i v-if="failure.fileName">{{ failure.fileName }}</i><br /> 178 <span v-if="failure.message">{{ translations.get("FileUpload_MacronisationFailed-Reason") }}: {{ failure.message }}</span> 179 </div> 180 181 <button class="btn-fab theme-flat" @click="dismissFailure(id)"> 182 <span class="material-icons">clear</span> 183 </button> 184 </li> 185 </ul> 186 </div> 187 </template> 188 189 <style scoped lang="scss"> 190 .audio-file-picker { 191 display: flex; 192 gap: 0.5em; 193 flex-direction: column; 194 195 input { 196 display: none; 197 } 198 199 .text-container { 200 cursor: pointer; 201 } 202 } 203 204 .input-bar { 205 display: grid; 206 align-items: stretch; 207 gap: 0.5em; 208 grid-template-columns: 1fr auto; 209 } 210 211 .uploaded-file-listing { 212 display: flex; 213 align-items: center; 214 215 padding: 3px; 216 gap: 5px; 217 218 border: 1px solid var(--bg-color); 219 border-radius: 3px; 220 border-left: 4px solid var(--bg-color); 221 background: rgba(var(--bg-color-raw), 0.1); 222 223 margin-right: 0.5em; 224 &:last-child { 225 margin-right: 0; 226 } 227 } 228 229 .transcription-error-container { 230 display: grid; 231 gap: 0.5em; 232 grid-template-columns: 1fr auto; 233 align-items: center; 234 235 border-left: 3px solid red; 236 } 237 </style> -
main/trunk/model-interfaces-dev/atea/macron-restoration/src/components/Snackbar.vue
r35784 r35901 1 <template>2 <div class="paper bar" :class="{ 'bar-show': hasContent }">3 {{ content }}4 </div>5 </template>6 7 <style lang="scss" scoped>8 .bar {9 position: absolute;10 bottom: 1em;11 left: 35%;12 13 opacity: 0;14 width: 30%;15 16 transition-duration: 250ms;17 --paper-color: #2E2E2E;18 color: white;19 }20 21 .bar-show {22 opacity: 1;23 }24 </style>25 26 1 <script> 27 2 export default { … … 108 83 } 109 84 </script> 85 86 <template> 87 <div class="paper bar" :class="{ 'bar-show': hasContent }"> 88 {{ content }} 89 </div> 90 </template> 91 92 <style lang="scss" scoped> 93 .bar { 94 position: absolute; 95 bottom: 1em; 96 left: 35%; 97 98 opacity: 0; 99 width: 30%; 100 101 transition-duration: 250ms; 102 --paper-color: #2E2E2E; 103 color: white; 104 } 105 106 .bar-show { 107 opacity: 1; 108 } 109 </style> -
main/trunk/model-interfaces-dev/atea/macron-restoration/src/components/TabBar.vue
r35723 r35901 1 <script> 2 export default { 3 name: "TabBar", 4 props: { 5 /** @type {Array<{label: String, id: String}} */ 6 tabs: Array, 7 modelValue: String 8 }, 9 emits: [ 10 "update:modelValue" 11 ], 12 computed: { 13 internalSelected: { 14 get() { 15 return this.modelValue; 16 }, 17 set(newValue) { 18 this.$emit("update:modelValue", newValue); 19 } 20 } 21 }, 22 watch: { 23 }, 24 methods: { 25 }, 26 beforeMount() { 27 if (this.modelValue === null && this.tabs.length > 0) { 28 this.$emit("update:modelValue", this.tabs[0].value); 29 } 30 } 31 } 32 </script> 33 1 34 <template> 2 35 <div class="container"> … … 50 83 } 51 84 </style> 52 53 <script>54 export default {55 name: "TabBar",56 props: {57 /** @type {Array<{label: String, id: String}} */58 tabs: Array,59 modelValue: String60 },61 emits: [62 "update:modelValue"63 ],64 computed: {65 internalSelected: {66 get() {67 return this.modelValue;68 },69 set(newValue) {70 this.$emit("update:modelValue", newValue);71 }72 }73 },74 watch: {75 },76 methods: {77 },78 beforeMount() {79 if (this.modelValue === null && this.tabs.length > 0) {80 this.$emit("update:modelValue", this.tabs[0].value);81 }82 }83 }84 </script> -
main/trunk/model-interfaces-dev/atea/macron-restoration/src/components/ToggleButton.vue
r35714 r35901 1 <template>2 <button class="base" @click="toggle" :class="{ 'toggled': myValue }" type="button">3 <slot />4 </button>5 </template>6 7 <style lang="scss" scoped>8 .base {9 @extend .btn-fab;10 color: var(--bg-color);11 background-color: var(--paper-color);12 box-shadow: var(--primary-box-shadow-thin);13 }14 15 .toggled {16 color: var(--fg-color);17 background-color: var(--bg-color);18 }19 </style>20 21 1 <script> 22 2 export default { … … 44 24 } 45 25 </script> 26 27 <template> 28 <button class="base" @click="toggle" :class="{ 'toggled': myValue }" type="button"> 29 <slot /> 30 </button> 31 </template> 32 33 <style lang="scss" scoped> 34 .base { 35 @extend .btn-fab; 36 color: var(--bg-color); 37 background-color: var(--paper-color); 38 box-shadow: var(--primary-box-shadow-thin); 39 } 40 41 .toggled { 42 color: var(--fg-color); 43 background-color: var(--bg-color); 44 } 45 </style>
Note:
See TracChangeset
for help on using the changeset viewer.