You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FileMimeType.vue 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <!--
  2. - @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
  3. -
  4. - @author Julius Härtl <jus@bitgrid.net>
  5. -
  6. - @license GNU AGPL version 3 or any later version
  7. -
  8. - This program is free software: you can redistribute it and/or modify
  9. - it under the terms of the GNU Affero General Public License as
  10. - published by the Free Software Foundation, either version 3 of the
  11. - License, or (at your option) any later version.
  12. -
  13. - This program is distributed in the hope that it will be useful,
  14. - but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. - GNU Affero General Public License for more details.
  17. -
  18. - You should have received a copy of the GNU Affero General Public License
  19. - along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. -
  21. -->
  22. <template>
  23. <div>
  24. <Multiselect :value="currentValue"
  25. :placeholder="t('workflowengine', 'Select a file type')"
  26. label="label"
  27. track-by="pattern"
  28. :options="options"
  29. :multiple="false"
  30. :tagging="false"
  31. @input="setValue">
  32. <template slot="singleLabel" slot-scope="props">
  33. <span v-if="props.option.icon" class="option__icon" :class="props.option.icon" />
  34. <img v-else
  35. class="option__icon-img"
  36. :src="props.option.iconUrl"
  37. alt="">
  38. <span class="option__title option__title_single">{{ props.option.label }}</span>
  39. </template>
  40. <template slot="option" slot-scope="props">
  41. <span v-if="props.option.icon" class="option__icon" :class="props.option.icon" />
  42. <img v-else
  43. class="option__icon-img"
  44. :src="props.option.iconUrl"
  45. alt="">
  46. <span class="option__title">{{ props.option.label }}</span>
  47. </template>
  48. </Multiselect>
  49. <input v-if="!isPredefined"
  50. type="text"
  51. :value="currentValue.pattern"
  52. :placeholder="t('workflowengine', 'e.g. httpd/unix-directory')"
  53. @input="updateCustom">
  54. </div>
  55. </template>
  56. <script>
  57. import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
  58. import valueMixin from './../../mixins/valueMixin'
  59. import { imagePath } from '@nextcloud/router'
  60. export default {
  61. name: 'FileMimeType',
  62. components: {
  63. Multiselect,
  64. },
  65. mixins: [
  66. valueMixin,
  67. ],
  68. data() {
  69. return {
  70. predefinedTypes: [
  71. {
  72. icon: 'icon-folder',
  73. label: t('workflowengine', 'Folder'),
  74. pattern: 'httpd/unix-directory',
  75. },
  76. {
  77. icon: 'icon-picture',
  78. label: t('workflowengine', 'Images'),
  79. pattern: '/image\\/.*/',
  80. },
  81. {
  82. iconUrl: imagePath('core', 'filetypes/x-office-document'),
  83. label: t('workflowengine', 'Office documents'),
  84. pattern: '/(vnd\\.(ms-|openxmlformats-|oasis\\.opendocument).*)$/',
  85. },
  86. {
  87. iconUrl: imagePath('core', 'filetypes/application-pdf'),
  88. label: t('workflowengine', 'PDF documents'),
  89. pattern: 'application/pdf',
  90. },
  91. ],
  92. }
  93. },
  94. computed: {
  95. options() {
  96. return [...this.predefinedTypes, this.customValue]
  97. },
  98. isPredefined() {
  99. const matchingPredefined = this.predefinedTypes.find((type) => this.newValue === type.pattern)
  100. if (matchingPredefined) {
  101. return true
  102. }
  103. return false
  104. },
  105. customValue() {
  106. return {
  107. icon: 'icon-settings-dark',
  108. label: t('workflowengine', 'Custom MIME type'),
  109. pattern: '',
  110. }
  111. },
  112. currentValue() {
  113. const matchingPredefined = this.predefinedTypes.find((type) => this.newValue === type.pattern)
  114. if (matchingPredefined) {
  115. return matchingPredefined
  116. }
  117. return {
  118. icon: 'icon-settings-dark',
  119. label: t('workflowengine', 'Custom mimetype'),
  120. pattern: this.newValue,
  121. }
  122. },
  123. },
  124. methods: {
  125. validateRegex(string) {
  126. const regexRegex = /^\/(.*)\/([gui]{0,3})$/
  127. const result = regexRegex.exec(string)
  128. return result !== null
  129. },
  130. setValue(value) {
  131. if (value !== null) {
  132. this.newValue = value.pattern
  133. this.$emit('input', this.newValue)
  134. }
  135. },
  136. updateCustom(event) {
  137. this.newValue = event.target.value
  138. this.$emit('input', this.newValue)
  139. },
  140. },
  141. }
  142. </script>
  143. <style scoped lang="scss">
  144. .multiselect, input[type='text'] {
  145. width: 100%;
  146. }
  147. .multiselect >>> .multiselect__content-wrapper li>span,
  148. .multiselect >>> .multiselect__single {
  149. display: flex;
  150. white-space: nowrap;
  151. overflow: hidden;
  152. text-overflow: ellipsis;
  153. }
  154. .option__icon {
  155. display: inline-block;
  156. min-width: 30px;
  157. background-position: left;
  158. }
  159. .option__icon-img {
  160. margin-right: 14px;
  161. }
  162. </style>