theme.tpl 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <style lang="scss">
  2. .page-theme {
  3. &:last-child {
  4. margin-bottom: 55px;
  5. }
  6. h2 {
  7. font-size: 28px;
  8. line-height: 28px;
  9. margin: 0;
  10. }
  11. ul {
  12. list-style: none;
  13. padding: 0;
  14. margin: 0;
  15. display: flex;
  16. flex-wrap: wrap;
  17. justify-content: space-between;
  18. }
  19. .theme-card {
  20. display: inline-block;
  21. height: 150px;
  22. height: 16vw;
  23. max-height: 230px;
  24. flex: 0 0 24%;
  25. cursor: default;
  26. vertical-align: bottom;
  27. }
  28. .theme-section {
  29. margin-bottom: 20px;
  30. }
  31. .second-section {
  32. margin-top: 60px;
  33. }
  34. }
  35. </style>
  36. <template>
  37. <div class="page-container page-theme">
  38. <section class="theme-section">
  39. <h2><%= 1 ></h2>
  40. <ul>
  41. <li class="theme-card" v-for="item in officialTheme" :key="item.name">
  42. <theme-card
  43. type="official"
  44. :config="item"
  45. @action="onAction"
  46. ></theme-card>
  47. </li>
  48. </ul>
  49. </section>
  50. <section class="theme-section second-section">
  51. <h2><%= 2 > ({{userThemeCount}}/{{maxUserTheme}})</h2>
  52. <ul>
  53. <li class="theme-card" v-if="showUserUpload">
  54. <theme-card
  55. type="upload"
  56. :config="{name: 'upload'}"
  57. @action="onAction"
  58. ></theme-card>
  59. </li>
  60. <li class="theme-card" v-for="item in displayUserTheme" :key="item.name">
  61. <theme-card
  62. type="user"
  63. :config="item"
  64. @action="onAction"
  65. ></theme-card>
  66. </li>
  67. </ul>
  68. </section>
  69. <el-dialog :visible.sync="copyDialogVisible">
  70. <el-form :model="copyForm" ref="copyForm" :rules="copyFormRule">
  71. <el-form-item label="<%= 3 >" prop="name">
  72. <el-input v-model="copyForm.name"></el-input>
  73. </el-form-item>
  74. </el-form>
  75. <div slot="footer" class="dialog-footer">
  76. <el-button @click="closeCopyForm">{{getActionDisplayName('cancel')}}</el-button>
  77. <el-button type="primary" @click="copyToUser">{{getActionDisplayName('confirm')}}</el-button>
  78. </div>
  79. </el-dialog>
  80. </div>
  81. </template>
  82. <script>
  83. import ThemeCard from '../../components/theme/theme-card.vue';
  84. import { themeList, eleThemeList } from '../../components/theme/theme-list.js';
  85. import { saveUserThemeToLocal, loadUserThemeFromLocal } from '../../components/theme/localstorage';
  86. import { getActionDisplayName } from '../../components/theme-configurator/utils/utils';
  87. const maxUserTheme = 8;
  88. export default {
  89. components: {
  90. ThemeCard
  91. },
  92. mounted() {
  93. this.userTheme = loadUserThemeFromLocal();
  94. if (!Array.isArray(this.userTheme)) {
  95. this.userTheme = [];
  96. saveUserThemeToLocal(this.userTheme);
  97. }
  98. },
  99. data() {
  100. return {
  101. userTheme: [],
  102. maxUserTheme,
  103. copyDialogVisible: false,
  104. copyForm: {},
  105. copyFormRule: {
  106. name: [{
  107. validator: this.validateCopyName,
  108. trigger: 'blur'
  109. }]
  110. }
  111. };
  112. },
  113. computed: {
  114. officialTheme() {
  115. return this.padEmpeyTheme(themeList.concat(this.$isEle ? eleThemeList : []));
  116. },
  117. userThemeCount() {
  118. return this.userTheme.length;
  119. },
  120. showUserUpload() {
  121. return this.userThemeCount < maxUserTheme;
  122. },
  123. displayUserTheme() {
  124. return this.padEmpeyTheme(this.userTheme, this.showUserUpload ? 1 : 0);
  125. }
  126. },
  127. methods: {
  128. getActionDisplayName(key) {
  129. return getActionDisplayName(key);
  130. },
  131. validateCopyName(rule, value, callback) {
  132. if (!value) {
  133. callback(new Error(this.getActionDisplayName('require-them-name')));
  134. } else if (this.filterUserThemeByName(value).length > 0) {
  135. callback(new Error(this.getActionDisplayName('duplicate-them-name')));
  136. } else {
  137. callback();
  138. }
  139. },
  140. filterUserThemeByName(name, include = true) {
  141. return this.userTheme.filter((theme) => (include ? theme.name === name : theme.name !== name));
  142. },
  143. padEmpeyTheme(theme, add = 0) {
  144. if (!theme.length) return [];
  145. const pad = 4 - ((theme.length + add) % 4);
  146. if (pad < 4) return theme.concat(Array(pad).fill({}));
  147. return theme;
  148. },
  149. onAction(name, item) {
  150. switch (name) {
  151. case 'copy':
  152. this.openCopyForm(item.theme);
  153. break;
  154. case 'upload':
  155. this.openCopyForm(item);
  156. break;
  157. case 'rename':
  158. this.openRenameForm(item.name);
  159. break;
  160. case 'delete':
  161. this.$confirm(this.getActionDisplayName('confirm-delete-theme'), this.getActionDisplayName('notice'), {
  162. confirmButtonText: this.getActionDisplayName('confirm'),
  163. cancelButtonText: this.getActionDisplayName('cancel'),
  164. type: 'warning'
  165. }).then(() => {
  166. this.deleteUserThemeByName(item.name);
  167. }).catch(() => {});
  168. break;
  169. default:
  170. return;
  171. }
  172. },
  173. deleteUserThemeByName(name) {
  174. this.userTheme = this.filterUserThemeByName(name, false);
  175. this.saveToLocal();
  176. },
  177. openRenameForm(name) {
  178. this.copyForm.oldname = name;
  179. this.copyDialogVisible = true;
  180. },
  181. openCopyForm(theme) {
  182. if (this.userTheme.length >= 8) {
  183. this.$message.error(this.getActionDisplayName('max-user-theme'));
  184. return;
  185. }
  186. this.copyForm.theme = theme;
  187. this.copyDialogVisible = true;
  188. },
  189. closeCopyForm() {
  190. this.copyDialogVisible = false;
  191. this.$nextTick(() => {
  192. this.copyForm = {};
  193. });
  194. },
  195. copyToUser() {
  196. this.$refs.copyForm.validate((valid) => {
  197. if (valid) {
  198. const { theme, name, oldname } = this.copyForm;
  199. if (theme) {
  200. // copy
  201. this.userTheme.push({
  202. update: Date.now(),
  203. name,
  204. theme
  205. });
  206. } else {
  207. // rename
  208. this.userTheme.forEach((config) => {
  209. if (config.name === oldname) {
  210. config.update = Date.now();
  211. config.name = name;
  212. }
  213. });
  214. }
  215. this.saveToLocal();
  216. this.closeCopyForm();
  217. }
  218. });
  219. },
  220. saveToLocal() {
  221. saveUserThemeToLocal(this.userTheme);
  222. }
  223. }
  224. };
  225. </script>