SettingsPage.vue 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. <template>
  2. <div ref="main" class="main" @click="close">
  3. <div class="mainWindow" @click.stop>
  4. <Window @close="close">
  5. <template slot="header">
  6. Настройки
  7. </template>
  8. <el-tabs type="border-card" tab-position="left" v-model="selectedTab">
  9. <!-- Профили ------------------------------------------------------------------------->
  10. <el-tab-pane label="Профили">
  11. <el-form :model="form" size="small" label-width="100px" @submit.native.prevent>
  12. <div class="partHeader">Профили устройств</div>
  13. <el-form-item label="">
  14. <div class="text">
  15. Выберите или добавьте профиль устройства, чтобы начать синхронизацию данных с сервером.
  16. При выборе "Нет" синхронизация отключается.
  17. </div>
  18. </el-form-item>
  19. <el-form-item label="Устройство">
  20. <el-select v-model="currentProfile" placeholder="">
  21. <el-option label="Нет" value=""></el-option>
  22. <el-option v-for="item in profilesArray"
  23. :key="item"
  24. :label="item"
  25. :value="item">
  26. </el-option>
  27. </el-select>
  28. </el-form-item>
  29. <el-form-item label="">
  30. <el-button @click="addProfile">Добавить</el-button>
  31. <el-button @click="delProfile">Удалить</el-button>
  32. </el-form-item>
  33. </el-form>
  34. <el-form :model="form" size="small" label-width="100px" @submit.native.prevent>
  35. <div class="partHeader">Ключ доступа</div>
  36. <el-form-item label="">
  37. <div class="text">
  38. Ключ доступа позволяет восстановить профили с настройками и список читаемых книг
  39. на другом устройстве. Для этого необходимо передать его через почту, мессенджер или другим способом.
  40. </div>
  41. <div>
  42. <b>{{ partialStorageKey }}</b> (часть вашего ключа)
  43. </div>
  44. </el-form-item>
  45. <el-form-item label="">
  46. <el-button style="width: 250px" @click="showServerStorageKey">Показать ключ доступа/ссылку</el-button>
  47. </el-form-item>
  48. <el-form-item label="">
  49. <el-button style="width: 250px" @click="enterServerStorageKey">Ввести ключ доступа</el-button>
  50. </el-form-item>
  51. <el-form-item label="">
  52. <el-button style="width: 250px" @click="generateServerStorageKey">Сгенерировать новый ключ</el-button>
  53. </el-form-item>
  54. <el-form-item label="">
  55. <div class="text">
  56. Рекомендуется сохранить ключ в надежном месте, чтобы всегда иметь возможность восстановить настройки,
  57. например, после переустановки ОС или чистки/смены браузера.<br>
  58. ПРЕДУПРЕЖДЕНИЕ! При утере ключа, НИКТО не сможет восстановить ваши настройки, т.к. все данные сжимаются
  59. и шифруются ключом доступа перед отправкой на сервер.
  60. </div>
  61. </el-form-item>
  62. </el-form>
  63. </el-tab-pane>
  64. <!-- Вид ------------------------------------------------------------------------->
  65. <el-tab-pane label="Вид">
  66. <el-form :model="form" size="small" label-width="120px" @submit.native.prevent>
  67. <div class="partHeader">Цвет</div>
  68. <el-form-item label="Текст">
  69. <el-col :span="12">
  70. <el-color-picker v-model="textColor" color-format="hex" :predefine="predefineTextColors"></el-color-picker>
  71. <span class="color-picked"><b>{{ textColor }}</b></span>
  72. </el-col>
  73. <el-col :span="5">
  74. <span style="position: relative; top: 20px;">Обои:</span>
  75. </el-col>
  76. </el-form-item>
  77. <el-form-item label="Фон">
  78. <el-col :span="12">
  79. <el-color-picker v-model="backgroundColor" color-format="hex" :predefine="predefineBackgroundColors" :disabled="wallpaper != ''"></el-color-picker>
  80. <span v-show="wallpaper == ''" class="color-picked"><b>{{ backgroundColor }}</b></span>
  81. </el-col>
  82. <el-col :span="11">
  83. <el-select v-model="wallpaper">
  84. <el-option label="Нет" value=""></el-option>
  85. <el-option label="1" value="paper1"></el-option>
  86. <el-option label="2" value="paper2"></el-option>
  87. <el-option label="3" value="paper3"></el-option>
  88. <el-option label="4" value="paper4"></el-option>
  89. <el-option label="5" value="paper5"></el-option>
  90. <el-option label="6" value="paper6"></el-option>
  91. <el-option label="7" value="paper7"></el-option>
  92. <el-option label="8" value="paper8"></el-option>
  93. <el-option label="9" value="paper9"></el-option>
  94. </el-select>
  95. </el-col>
  96. </el-form-item>
  97. </el-form>
  98. <el-form :model="form" size="mini" label-width="120px" @submit.native.prevent>
  99. <div class="partHeader">Шрифт</div>
  100. <el-form-item label="Локальный/веб">
  101. <el-col :span="11">
  102. <el-select v-model="fontName" placeholder="Шрифт" :disabled="webFontName != ''">
  103. <el-option v-for="item in fonts"
  104. :key="item.name"
  105. :label="item.label"
  106. :value="item.name">
  107. </el-option>
  108. </el-select>
  109. </el-col>
  110. <el-col :span="1">
  111. &nbsp;
  112. </el-col>
  113. <el-col :span="11">
  114. <el-tooltip :open-delay="500" effect="light" placement="top">
  115. <template slot="content">
  116. Веб шрифты дают большое разнообразие,<br>
  117. однако есть шанс, что шрифт будет загружаться<br>
  118. очень медленно или вовсе не загрузится
  119. </template>
  120. <el-select v-model="webFontName">
  121. <el-option label="Нет" value=""></el-option>
  122. <el-option v-for="item in webFonts"
  123. :key="item.name"
  124. :value="item.name">
  125. </el-option>
  126. </el-select>
  127. </el-tooltip>
  128. </el-col>
  129. </el-form-item>
  130. <el-form-item label="Размер">
  131. <el-col :span="17">
  132. <el-input-number v-model="fontSize" :min="5" :max="200"></el-input-number>
  133. </el-col>
  134. <el-col :span="1">
  135. <a href="https://fonts.google.com/?subset=cyrillic" target="_blank">Примеры</a>
  136. </el-col>
  137. </el-form-item>
  138. <el-form-item label="Сдвиг">
  139. <el-tooltip :open-delay="500" effect="light">
  140. <template slot="content">
  141. Сдвиг шрифта по вертикали в процентах от размера.<br>
  142. Отрицательное значение сдвигает вверх, положительное -<br>
  143. вниз. Значение зависит от метрики шрифта.
  144. </template>
  145. <el-input-number v-model="vertShift" :min="-100" :max="100"></el-input-number>
  146. </el-tooltip>
  147. </el-form-item>
  148. <el-form-item label="Стиль">
  149. <el-col :span="8">
  150. <el-checkbox v-model="fontBold">Жирный</el-checkbox>
  151. </el-col>
  152. <el-col :span="8">
  153. <el-checkbox v-model="fontItalic">Курсив</el-checkbox>
  154. </el-col>
  155. </el-form-item>
  156. </el-form>
  157. <el-form :model="form" size="mini" label-width="120px" @submit.native.prevent>
  158. <div class="partHeader">Текст</div>
  159. <el-form-item label="Интервал">
  160. <el-input-number v-model="lineInterval" :min="0" :max="200"></el-input-number>
  161. </el-form-item>
  162. <el-form-item label="Параграф">
  163. <el-input-number v-model="p" :min="0" :max="2000"></el-input-number>
  164. </el-form-item>
  165. <el-form-item label="Отступ">
  166. <el-col :span="11">
  167. <el-tooltip :open-delay="500" effect="light">
  168. <template slot="content">
  169. Слева/справа
  170. </template>
  171. <el-input-number v-model="indentLR" :min="0" :max="2000"></el-input-number>
  172. </el-tooltip>
  173. </el-col>
  174. <el-col :span="1">
  175. &nbsp;
  176. </el-col>
  177. <el-col :span="11">
  178. <el-tooltip :open-delay="500" effect="light">
  179. <template slot="content">
  180. Сверху/снизу
  181. </template>
  182. <el-input-number v-model="indentTB" :min="0" :max="2000"></el-input-number>
  183. </el-tooltip>
  184. </el-col>
  185. </el-form-item>
  186. <el-form-item label="Сдвиг">
  187. <el-tooltip :open-delay="500" effect="light">
  188. <template slot="content">
  189. Сдвиг текста по вертикали в процентах от размера шрифта.<br>
  190. Отрицательное значение сдвигает вверх, положительное -<br>
  191. вниз.
  192. </template>
  193. <el-input-number v-model="textVertShift" :min="-100" :max="100"></el-input-number>
  194. </el-tooltip>
  195. </el-form-item>
  196. <el-form-item label="Скроллинг">
  197. <el-col :span="11">
  198. <el-tooltip :open-delay="500" effect="light">
  199. <template slot="content">
  200. Замедление скроллинга в миллисекундах.<br>
  201. Определяет время, за которое текст<br>
  202. прокручивается на одну строку.
  203. </template>
  204. <el-input-number v-model="scrollingDelay" :min="1" :max="10000"></el-input-number>
  205. </el-tooltip>
  206. </el-col>
  207. <el-col :span="1">
  208. &nbsp;
  209. </el-col>
  210. <el-col :span="11">
  211. <el-tooltip :open-delay="500" effect="light" placement="top">
  212. <template slot="content">
  213. Вид скроллинга: линейный,<br>
  214. ускорение-замедление и пр.
  215. </template>
  216. <el-select v-model="scrollingType">
  217. <el-option value="linear"></el-option>
  218. <el-option value="ease"></el-option>
  219. <el-option value="ease-in"></el-option>
  220. <el-option value="ease-out"></el-option>
  221. <el-option value="ease-in-out"></el-option>
  222. </el-select>
  223. </el-tooltip>
  224. </el-col>
  225. </el-form-item>
  226. <el-form-item label="Выравнивание">
  227. <el-checkbox v-model="textAlignJustify">По ширине</el-checkbox>
  228. <el-checkbox v-model="wordWrap">Перенос по слогам</el-checkbox>
  229. </el-form-item>
  230. <el-form-item label="Обработка">
  231. <el-checkbox v-model="cutEmptyParagraphs">Убирать пустые строки</el-checkbox>
  232. </el-form-item>
  233. <el-form-item label="">
  234. <el-col :span="12">
  235. Добавлять пустые
  236. </el-col>
  237. <el-input-number v-model="addEmptyParagraphs" :min="0" :max="2"></el-input-number>
  238. </el-form-item>
  239. <el-form-item label="Изображения">
  240. <el-col :span="11">
  241. <el-checkbox v-model="showImages">Показывать</el-checkbox>
  242. </el-col>
  243. <el-col :span="1">
  244. &nbsp;
  245. </el-col>
  246. <el-col :span="11">
  247. <el-tooltip :open-delay="500" effect="light" placement="top">
  248. <template slot="content">
  249. Выносить все изображения в центр экрана
  250. </template>
  251. <el-checkbox v-model="showInlineImagesInCenter" @change="needReload" :disabled="!showImages">Инлайн в центр</el-checkbox>
  252. </el-tooltip>
  253. </el-col>
  254. </el-form-item>
  255. <el-form-item label="">
  256. <el-checkbox v-model="imageFitWidth" :disabled="!showImages">Ширина не более размера экрана</el-checkbox>
  257. </el-form-item>
  258. <el-form-item label="">
  259. <el-col :span="12">
  260. Высота не более
  261. </el-col>
  262. <el-tooltip :open-delay="500" effect="light" placement="top">
  263. <template slot="content">
  264. Определяет высоту изображения количеством строк.<br>
  265. В случае превышения высоты, изображение будет<br>
  266. уменьшено с сохранением пропорций так, чтобы<br>
  267. помещаться в указанное количество строк.
  268. </template>
  269. <el-input-number v-model="imageHeightLines" :min="1" :max="100" :disabled="!showImages"></el-input-number>
  270. </el-tooltip>
  271. </el-form-item>
  272. </el-form>
  273. <el-form :model="form" size="mini" label-width="120px" @submit.native.prevent>
  274. <div class="partHeader">Строка статуса</div>
  275. <el-form-item label="Статус">
  276. <el-checkbox v-model="showStatusBar">Показывать</el-checkbox>
  277. <el-checkbox v-model="statusBarTop" :disabled="!showStatusBar">Вверху/внизу</el-checkbox>
  278. </el-form-item>
  279. <el-form-item label="Высота">
  280. <el-input-number v-model="statusBarHeight" :min="5" :max="100" :disabled="!showStatusBar"></el-input-number>
  281. </el-form-item>
  282. <el-form-item label="Прозрачность">
  283. <el-input-number v-model="statusBarColorAlpha" :min="0" :max="1" :precision="2" :step="0.1" :disabled="!showStatusBar"></el-input-number>
  284. </el-form-item>
  285. </el-form>
  286. </el-tab-pane>
  287. <!-- Листание ------------------------------------------------------------------------->
  288. <el-tab-pane label="Листание">
  289. <el-form :model="form" size="mini" label-width="120px" @submit.native.prevent>
  290. <div class="partHeader">Анимация</div>
  291. <el-form-item label="Тип">
  292. <el-col :span="11">
  293. <el-select v-model="pageChangeAnimation">
  294. <el-option label="Нет" value=""></el-option>
  295. <el-option label="Вверх-вниз" value="downShift"></el-option>
  296. <el-option label="Вправо-влево" value="rightShift"></el-option>
  297. <el-option label="Протаивание" value="thaw"></el-option>
  298. <el-option label="Мерцание" value="blink"></el-option>
  299. </el-select>
  300. </el-col>
  301. </el-form-item>
  302. <el-form-item label="Скорость">
  303. <el-input-number v-model="pageChangeAnimationSpeed" :min="0" :max="100" :disabled="pageChangeAnimation == ''"></el-input-number>
  304. </el-form-item>
  305. </el-form>
  306. <el-form :model="form" size="mini" label-width="120px" @submit.native.prevent>
  307. <div class="partHeader">Другое</div>
  308. <el-form-item label="Страница">
  309. <el-tooltip :open-delay="500" effect="light">
  310. <template slot="content">
  311. Переносить последнюю строку страницы<br>
  312. в начало следующей при листании
  313. </template>
  314. <el-checkbox v-model="keepLastToFirst">Переносить последнюю строку</el-checkbox>
  315. </el-tooltip>
  316. </el-form-item>
  317. </el-form>
  318. </el-tab-pane>
  319. <!-- Прочее ------------------------------------------------------------------------->
  320. <el-tab-pane label="Прочее">
  321. <el-form :model="form" size="mini" label-width="120px" @submit.native.prevent>
  322. <el-form-item label="Управление">
  323. <el-checkbox v-model="clickControl">Включить управление кликом</el-checkbox>
  324. </el-form-item>
  325. <el-form-item label="Подсказка">
  326. <el-tooltip :open-delay="500" effect="light">
  327. <template slot="content">
  328. Показывать или нет подсказку при каждой загрузке книги
  329. </template>
  330. <el-checkbox v-model="showClickMapPage" :disabled="!clickControl">Показывать области управления кликом</el-checkbox>
  331. </el-tooltip>
  332. </el-form-item>
  333. <el-form-item label="Подсказка">
  334. <el-tooltip :open-delay="500" effect="light">
  335. <template slot="content">
  336. Мерцать сообщением в строке статуса и на кнопке<br>
  337. обновления при загрузке книги из кэша
  338. </template>
  339. <el-checkbox v-model="blinkCachedLoad">Предупреждать о загрузке из кэша</el-checkbox>
  340. </el-tooltip>
  341. </el-form-item>
  342. <el-form-item label="URL">
  343. <el-tooltip :open-delay="500" effect="light">
  344. <template slot="content">
  345. Добавление параметра "__p" в строке браузера<br>
  346. позволяет передавать ссылку на книгу в читалке<br>
  347. без потери текущей позиции. Однако в этом случае<br>
  348. при листании забивается история браузера, т.к. на<br>
  349. каждое изменение позиции происходит смена URL.
  350. </template>
  351. <el-checkbox v-model="allowUrlParamBookPos">Добавлять параметр "__p"</el-checkbox>
  352. </el-tooltip>
  353. </el-form-item>
  354. <el-form-item label="Парсинг">
  355. <el-tooltip :open-delay="500" effect="light">
  356. <template slot="content">
  357. Включение этой опции позволяет делать предварительную<br>
  358. обработку текста в ленивом режиме сразу после загрузки<br>
  359. книги. Это может повысить отзывчивость читалки, но<br>
  360. нагружает процессор каждый раз при открытии книги.
  361. </template>
  362. <el-checkbox v-model="lazyParseEnabled">Предварительная обработка текста</el-checkbox>
  363. </el-tooltip>
  364. </el-form-item>
  365. <el-form-item label="Копирование">
  366. <el-tooltip :open-delay="500" effect="light">
  367. <template slot="content">
  368. Загружать весь текст в окно<br>
  369. копирования текста со страницы
  370. </template>
  371. <el-checkbox v-model="copyFullText">Загружать весь текст</el-checkbox>
  372. </el-tooltip>
  373. </el-form-item>
  374. </el-form>
  375. </el-tab-pane>
  376. <!-- Сброс ------------------------------------------------------------------------->
  377. <el-tab-pane label="Сброс">
  378. <el-button @click="setDefaults">Установить по-умолчанию</el-button>
  379. </el-tab-pane>
  380. </el-tabs>
  381. </Window>
  382. </div>
  383. </div>
  384. </template>
  385. <script>
  386. //-----------------------------------------------------------------------------
  387. import Vue from 'vue';
  388. import Component from 'vue-class-component';
  389. //import _ from 'lodash';
  390. import Window from '../../share/Window.vue';
  391. import rstore from '../../../store/modules/reader';
  392. export default @Component({
  393. components: {
  394. Window,
  395. },
  396. data: function() {
  397. return Object.assign({}, rstore.settingDefaults);
  398. },
  399. watch: {
  400. form: function(newValue) {
  401. this.commit('reader/setSettings', newValue);
  402. },
  403. fontBold: function(newValue) {
  404. this.fontWeight = (newValue ? 'bold' : '');
  405. },
  406. fontItalic: function(newValue) {
  407. this.fontStyle = (newValue ? 'italic' : '');
  408. },
  409. vertShift: function(newValue) {
  410. const font = (this.webFontName ? this.webFontName : this.fontName);
  411. this.fontShifts = Object.assign({}, this.fontShifts, {[font]: newValue});
  412. this.fontVertShift = newValue;
  413. },
  414. fontName: function(newValue) {
  415. const font = (this.webFontName ? this.webFontName : newValue);
  416. this.vertShift = this.fontShifts[font] || 0;
  417. },
  418. webFontName: function(newValue) {
  419. const font = (newValue ? newValue : this.fontName);
  420. this.vertShift = this.fontShifts[font] || 0;
  421. },
  422. },
  423. })
  424. class SettingsPage extends Vue {
  425. selectedTab = null;
  426. form = {};
  427. fontBold = false;
  428. fontItalic = false;
  429. vertShift = 0;
  430. webFonts = [];
  431. fonts = [];
  432. created() {
  433. this.commit = this.$store.commit;
  434. this.reader = this.$store.state.reader;
  435. this.form = Object.assign({}, this.settings);
  436. for (let prop in rstore.settingDefaults) {
  437. this[prop] = this.form[prop];
  438. this.$watch(prop, (newValue) => {
  439. this.form = Object.assign({}, this.form, {[prop]: newValue});
  440. });
  441. }
  442. this.fontBold = (this.fontWeight == 'bold');
  443. this.fontItalic = (this.fontStyle == 'italic');
  444. this.fonts = rstore.fonts;
  445. this.webFonts = rstore.webFonts;
  446. const font = (this.webFontName ? this.webFontName : this.fontName);
  447. this.vertShift = this.fontShifts[font] || 0;
  448. }
  449. get settings() {
  450. return this.$store.state.reader.settings;
  451. }
  452. get profiles() {
  453. return this.$store.state.reader.profiles;
  454. }
  455. get profilesArray() {
  456. return Object.keys(this.profiles);
  457. }
  458. get currentProfile() {
  459. return this.$store.state.reader.currentProfile;
  460. }
  461. set currentProfile(newValue) {
  462. this.commit('reader/setCurrentProfile', newValue);
  463. }
  464. get partialStorageKey() {
  465. return this.serverStorageKey.substr(0, 7) + '***';
  466. }
  467. get serverStorageKey() {
  468. return this.$store.state.reader.serverStorageKey;
  469. }
  470. get predefineTextColors() {
  471. return [
  472. '#ffffff',
  473. '#000000',
  474. '#202020',
  475. '#323232',
  476. '#aaaaaa',
  477. '#00c0c0',
  478. ];
  479. }
  480. get predefineBackgroundColors() {
  481. return [
  482. '#ffffff',
  483. '#000000',
  484. '#202020',
  485. '#ebe2c9',
  486. '#cfdc99',
  487. '#478355',
  488. '#a6caf0',
  489. '#909080',
  490. '#808080',
  491. '#c8c8c8',
  492. ];
  493. }
  494. needReload() {
  495. this.$notify.warning({message: 'Необходимо обновить страницу (F5), чтобы изменения возымели эффект'});
  496. }
  497. close() {
  498. this.$emit('settings-toggle');
  499. }
  500. async setDefaults() {
  501. try {
  502. if (await this.$confirm('Подтвердите установку настроек по-умолчанию', '', {
  503. confirmButtonText: 'OK',
  504. cancelButtonText: 'Отмена',
  505. type: 'warning'
  506. })) {
  507. this.form = Object.assign({}, rstore.settingDefaults);
  508. for (let prop in rstore.settingDefaults) {
  509. this[prop] = this.form[prop];
  510. }
  511. }
  512. } catch (e) {
  513. //
  514. }
  515. }
  516. async addProfile() {
  517. try {
  518. const result = await this.$prompt('Введите произвольное название для профиля устройства', '', {
  519. confirmButtonText: 'OK',
  520. cancelButtonText: 'Отмена',
  521. inputValidator: (str) => { if (str.length > 50) return 'Слишком длинное название'; else return true; },
  522. });
  523. if (result.value) {
  524. if (this.profiles[result.value]) {
  525. this.$alert('Такой профиль уже существует', 'Ошибка');
  526. } else {
  527. this.currentProfile = result.value;
  528. await this.$nextTick();
  529. const newProfiles = Object.assign({}, this.profiles, {[result.value]: 1});
  530. this.commit('reader/setProfiles', newProfiles);
  531. }
  532. }
  533. } catch (e) {
  534. //
  535. }
  536. }
  537. async delProfile() {
  538. }
  539. async showServerStorageKey() {
  540. }
  541. async enterServerStorageKey() {
  542. }
  543. async generateServerStorageKey() {
  544. }
  545. keyHook(event) {
  546. if (event.type == 'keydown' && event.code == 'Escape') {
  547. this.close();
  548. }
  549. return true;
  550. }
  551. }
  552. //-----------------------------------------------------------------------------
  553. </script>
  554. <style scoped>
  555. .main {
  556. position: absolute;
  557. width: 100%;
  558. height: 100%;
  559. z-index: 60;
  560. display: flex;
  561. flex-direction: column;
  562. justify-content: center;
  563. align-items: center;
  564. }
  565. .mainWindow {
  566. height: 70%;
  567. display: flex;
  568. position: relative;
  569. }
  570. .text {
  571. font-size: 90%;
  572. line-height: 130%;
  573. }
  574. .el-form {
  575. border-top: 2px solid #bbbbbb;
  576. margin-bottom: 5px;
  577. }
  578. .el-form-item {
  579. padding: 0;
  580. margin: 0;
  581. margin-bottom: 5px;
  582. }
  583. .color-picked {
  584. margin-left: 10px;
  585. position: relative;
  586. top: -11px;
  587. }
  588. .partHeader {
  589. font-weight: bold;
  590. margin-bottom: 5px;
  591. }
  592. .el-tabs {
  593. flex: 1;
  594. display: flex;
  595. }
  596. .el-tab-pane {
  597. flex: 1;
  598. display: flex;
  599. flex-direction: column;
  600. width: 420px;
  601. overflow-y: auto;
  602. padding: 15px;
  603. }
  604. </style>