seyason 4 лет назад
Родитель
Сommit
8befce441c
43 измененных файлов с 14860 добавлено и 0 удалено
  1. 124 0
      fhKeeper/formulahousekeeper/timesheet/src/views/pdf/pdfview.vue
  2. 429 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/fileCenter.vue
  3. 650 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/info.vue
  4. 1453 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue
  5. 411 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/summary.vue
  6. 549 0
      fhKeeper/formulahousekeeper/timesheet/src/views/task/list.vue
  7. 72 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/dark/content.css
  8. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/dark/content.min.css
  9. 67 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/default/content.css
  10. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/default/content.min.css
  11. 72 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/document/content.css
  12. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/document/content.min.css
  13. 68 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/writer/content.css
  14. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/writer/content.min.css
  15. 714 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.css
  16. 726 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.inline.css
  17. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.inline.min.css
  18. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.min.css
  19. 29 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.mobile.css
  20. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.mobile.min.css
  21. BIN
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/fonts/tinymce-mobile.woff
  22. 3029 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.css
  23. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.min.css
  24. 673 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.mobile.css
  25. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.mobile.min.css
  26. 37 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.shadowdom.css
  27. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css
  28. 732 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.css
  29. 726 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.inline.css
  30. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.inline.min.css
  31. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.min.css
  32. 29 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.mobile.css
  33. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.mobile.min.css
  34. BIN
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff
  35. 3029 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.css
  36. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.min.css
  37. 673 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.mobile.css
  38. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.mobile.min.css
  39. 37 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.shadowdom.css
  40. 7 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.shadowdom.min.css
  41. 419 0
      fhKeeper/formulahousekeeper/timesheet/static/tinymce/zh_CN.js
  42. BIN
      fhKeeper/formulahousekeeper/timesheet/static/upload/0b7c576ac90b4503bba8c2b36c15517a.pdf
  43. BIN
      fhKeeper/formulahousekeeper/timesheet/static/upload/222.pdf

+ 124 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/pdf/pdfview.vue

@@ -0,0 +1,124 @@
+<template>
+    <div v-loading="loading"
+    element-loading-text="加载中,请稍后..."
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)">
+    
+    <pdf ref="pdf"
+      :src="src" 
+      v-for="i in pageCount" 
+      :key="i"
+      :page="i"
+      > 
+      
+    </pdf>
+    <!-- <div class="toolBar" style="display:flex;" justify="center">
+      <van-col span="8" style="text-align: center;"><a @click="changePdfPage(0)" :disabled="currentPage==1">上一页</a></van-col>
+      <van-col span="8" style="text-align: center;"><span>{{currentPage}} / {{pageCount}}</span></van-col>
+      <van-col span="8" style="text-align: center;"><a @click="changePdfPage(1)" :disabled="currentPage==pageCount">下一页</a></van-col>
+    </div> -->
+  </div>
+</template>
+
+<script>
+import pdf from 'vue-pdf'
+var headers = {
+    'Authorization': 'Bearer SOME_TOKEN',
+    'x-ipp-device-uuid': 'SOME_UUID',
+    'x-ipp-client': 'SOME_ID',
+    'x-ipp-client-version': 'SOME_VERSION'
+};
+
+// var loadingTask = pdf.createLoadingTask({
+//     url:'/static/upload/222.pdf',
+//     httpHeaders:headers
+// });
+var loadingTask;
+  export default {
+    components: {pdf},
+    data () {
+      return {
+        loading:true,
+        serverFname:null,
+        fileName:null,
+        file:null,
+        currentPage: 1, // pdf文件页码
+        pageCount: 1, // pdf文件总页数
+        fileType: 'pdf', // 文件类型     
+        src: null, //'/upload/1d43c8c07f5944a9a1dd9e5e0197aa00.pdf', // pdf文件地址,
+      }
+    },  
+    created(){
+      
+  },
+    methods: {
+      handleError(e) {
+        this.$toast.clear();
+        this.$toast.fail('加载失败:'+e);
+
+      },
+      // 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
+      changePdfPage (val) {
+        // console.log(val)
+        if (val === 0 && this.currentPage > 1) {
+          this.currentPage--
+          // console.log(this.currentPage)
+        }
+        if (val === 1 && this.currentPage < this.pageCount) {
+          this.currentPage++
+          // console.log(this.currentPage)
+        }
+      },
+      // pdf加载时
+      loadPdfHandler (e) {
+        this.currentPage = 1 // 加载的时候先加载第一页
+      },
+      back() {
+         history.back();
+      },
+    },
+    mounted(){
+      console.log(sessionStorage.getItem("serverFname"));
+      loadingTask = pdf.createLoadingTask({
+          url:sessionStorage.getItem("serverFname"),
+          httpHeaders:headers
+      });
+      this.src = loadingTask;
+      this.serverFname = sessionStorage.getItem("serverFname");
+      this.fileName = sessionStorage.getItem("fileName");
+      loadingTask.promise.then(pdf => {
+        this.pageCount = pdf.numPages;
+        console.log('pageCount======'+this.pageCount);
+        this.loading = false;
+      }).catch(err => {
+        console.error('pdf 加载失败', err);
+        this.loading = false;
+        this.$message({
+                            message: "加载失败",
+                            type: 'error'
+                        });
+      })
+    }
+  }
+</script>
+
+<style>
+.toolBar {
+    position:fixed; bottom:0;left:0; width:100%;
+    padding:10px;
+    background:#ddd;
+}
+.control_bar {
+  float:right;
+  position:fixed;
+  bottom:80px;
+  right:0px;
+  margin-right:3px; 
+  background:#ddd;
+  opacity:0.4;
+  filter:alpha(opacity=40); 
+  border-radius:3px;
+  padding:3px;
+}
+</style>
+

+ 429 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/project/fileCenter.vue

@@ -0,0 +1,429 @@
+<template>
+    <section >
+        <div :style="'background:#f7f7f7;padding:10px 50px;height:'+tableHeight+'px;'">
+        <!--工具条-->
+        <!-- <el-col :span="24" class="toolbar" style="padding-bottom: 0px;background:#fff;border-bottom:1px solid #f7f7f7;">
+            <el-form :inline="true">
+                <el-form-item label="文件库">
+                </el-form-item>
+                <el-form-item style="float:right;">
+                    <el-link type="primary" :underline="false" @click="createFolder()"><i class="el-icon-folder-add"></i><span style="margin-left:5px;">创建文件夹</span></el-link>
+                    <el-upload ref="upload" action="#" :http-request="uploadFile" :show-file-list="false" :limit="1" style="display:inline-block;">
+                        <el-link type="primary" :underline="false" style="margin-left:10px;"><i class="iconfont firerock-iconshangchuan"></i><span style="margin-left:5px;">文件上传</span></el-link>
+                    </el-upload>
+                </el-form-item>
+            </el-form>
+        </el-col> -->
+        <div style="padding: 20px;background:#fff;border-bottom:1px solid #ddd;font-weight:500;font-size:15px;">
+            <span @click="viewFolder(null)">文件库</span>
+            <span v-for="path in pathList" :key="path.id" @click="viewFolder(path)"> / {{path.documentName}}</span>
+            <span style="float:right;">
+                    <el-link type="primary" :underline="false" @click="createFolder"><i class="el-icon-folder-add"></i><span style="margin-left:5px;">创建文件夹</span></el-link>
+                    <el-upload ref="upload" action="#" :http-request="uploadFile" :show-file-list="false" :limit="1" style="display:inline-block;">
+                        <el-link type="primary" :underline="false" style="margin-left:10px;"><i class="iconfont firerock-iconshangchuan"></i><span style="margin-left:5px;">文件上传</span></el-link>
+                    </el-upload>
+            </span>
+        </div>
+        <div>
+        <el-col :span="6" style="border-right: 1px solid #EBEEF5;">
+            <el-table :data="recentFiles" highlight-current-row :height="tableHeight">
+                <el-table-column prop="documentName" label="近期文件" sortable="true">
+                    <template slot-scope="scope">
+                        <el-link @click.stop.native="viewOnline(scope.row)">
+                        <i v-if="scope.row.documentType == -1" class="iconfont firerock-iconfile fileTypeIcon"></i>
+                        <i v-if="scope.row.documentType != -1" :class="docTypeList[scope.row.documentType]+' fileTypeIcon'" ></i>
+                        <span style="margin-left:8px;color:#262626;" @click="viewOnline(scope.row)">{{scope.row.documentName}}</span>
+                        </el-link>
+                    </template>
+                </el-table-column>
+                <el-table-column width="60">
+                <el-button icon="el-icon-download"  circle size="mini" style="margin-left:10px;" @click.stop.native="downloadByA(scope.row)"></el-button>
+                </el-table-column>
+            </el-table>
+        </el-col>
+        <el-col :span="18" >
+            <el-table :data="list" highlight-current-row :height="tableHeight" style="width: 100%;"  @row-click="rowClick" @cell-mouse-enter="cursorOver" >
+                <!-- <el-table-column prop="folder" ></el-table-column> -->
+                <el-table-column prop="documentName" label="名称" >
+                    <template slot-scope="scope" >
+                        <div v-if="scope.row.isFolder==1">
+                            <i class="el-icon-folder fileTypeIcon"></i><span style="margin-left:8px;color:#262626;" >{{scope.row.documentName}}</span>
+                        </div>
+                        <div v-if="scope.row.isFolder==0">
+                            <el-link @click.stop.native="viewOnline(scope.row)">
+                            <i v-if="scope.row.documentType == -1" class="iconfont firerock-iconfile fileTypeIcon"></i>
+                            <i v-if="scope.row.documentType != -1" :class="docTypeList[scope.row.documentType]+' fileTypeIcon'"></i>
+                            <span style="margin-left:8px;color:#262626;" >{{scope.row.documentName}}</span></el-link>
+                        </div>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="size" label="大小" width="100">
+                    <template slot-scope="scope">
+                        {{scope.row.isFolder==0?scope.row.size:"-"}}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="creatorName" label="创建者" width="100"></el-table-column>
+                <el-table-column prop="indate" label="创建时间" sortable="true" width="100"></el-table-column>
+                <el-table-column width="140">
+                    <template slot-scope="scope" >
+                    <div v-show="currentDataId == scope.row.id">
+                        <el-button v-if="scope.row.isFolder == 0" icon="el-icon-download"  circle size="mini"  @click.stop.native="downloadByA(scope.row)"></el-button>
+                        <el-button icon="el-icon-edit" circle size="mini" style="margin-left:10px;" @click.stop.native="showEditName(scope.row)"></el-button>
+                        <el-button icon="el-icon-delete"  circle size="mini" style="margin-left:10px;" @click.stop.native="deleteItem(scope.row)"></el-button>
+                    </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </el-col>
+        </div>
+        
+        <!--新增界面-->
+        <el-dialog title="文件上传" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
+            <el-form ref="form1" :model="addForm" :rules="rules" label-width="120px">
+                <el-form-item label="截止日期" prop="planEndDate">
+                    <el-date-picker v-model="addForm.planEndDate" v-if="user.company.packageProject==1" 
+                     :editable="false" 
+                     format="yyyy-MM-dd" 
+                     value-format="yyyy-MM-dd"
+                     :clearable="false" type="date" 
+                     placeholder="选择日期"></el-date-picker>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="addFormVisible = false">取消</el-button>
+                <el-button type="primary" @click="submitInsert" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+
+         <!-- 文件夹弹出框 -->
+        <el-dialog title="新增/修改文件夹" v-if="addFolderDialog" :visible.sync="addFolderDialog" :close-on-click-modal="false" customClass="customWidth" width="300px">
+            <el-form ref="form2" :model="folderForm" :rules="rules" >
+                <el-form-item prop="documentName">
+                    <el-input v-model="folderForm.documentName" placeholder="请输入文件夹名称" maxlength="25"
+                        show-word-limit clearable></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="addFolder" style="width:100%;" >保存</el-button>
+            </div>
+        </el-dialog>
+        </div>
+    </section>
+</template>
+<style scoped>
+.fileTypeIcon {
+    color:#20a0ff;font-size:20px;
+}
+</style>
+<script>
+    import util from "../../common/js/util";
+
+    export default {
+        data() {
+            return {
+                pathList:[],
+                currentDataId: null,
+                docTypeList:["iconfont firerock-iconJPG","iconfont firerock-iconword","iconfont firerock-icontxt"
+                ,"iconfont firerock-iconex","iconfont firerock-iconZip","iconfont firerock-iconvideo"
+                ,"iconfont firerock-iconaudio","iconfont firerock-iconPDF"],
+                rules: {
+                    documentName: [{ required: true, message: "请输入文件夹名称", trigger: "blur" }],
+                },
+                folderForm:{},
+                addFolderDialog: false,
+                moveToTrashDialog:false,
+                list:[],
+                parentFid:null,
+                upLoading:false,
+                keyword:null,
+                user: JSON.parse(sessionStorage.getItem("user")),
+                recentFiles: [],
+                addFormVisible: false,
+                addLoading: false,
+                curProjectId:null,
+                title: "",
+                addForm: {
+                    
+                },
+            };
+        },
+        methods: {
+            cursorOver(row, column, cell, event) {
+                this.currentDataId = row.id;
+            },
+            viewOnline(row) {
+                this.http.post('/pdf-file/getProjectFile', {fileId: row.id},
+                res => {
+                    if (res.code == "ok") {
+                        console.log(res.data+'----'+row.documentName);
+                        let routeUrl = this.$router.resolve({
+                            path: "/viewonline",
+                            params: {serverFname:res.data, fileName:row.documentName}
+                        });
+                        sessionStorage.setItem("serverFname",res.data);
+                        sessionStorage.setItem("fileName",row.documentName);
+                        console.log(routeUrl.href);
+                        window.open(routeUrl.href, '_blank');
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error,
+                        type: 'error'
+                    });
+                })
+            },
+            deleteItem(row) {
+                this.$confirm("确认要移到回收站吗?", "提示", {
+                    //type: 'warning'
+                }).then(() => {
+                    this.http.post('/document/delete', row,
+                    res => {
+                        if (res.code == "ok") {
+                            this.addFolderDialog = false;
+                            this.getRecentList();
+                            this.getList();
+                        } else {
+                            this.$message({
+                            message: res.msg,
+                            type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                    });
+                });
+            },
+            viewFolder(item) {
+                var list = [];
+                if (item == null) {
+                    //查看根目录
+                    this.parentFid = null;
+                } else {
+                    this.parentFid = item.id;
+                    for (var i=0;i<this.pathList.length; i++) {
+                        list.push(this.pathList[i]);
+                        if (this.pathList[i].id == item.id) {
+                            break;
+                        }
+                    }
+                }
+                
+                console.log('list===='+list);
+                this.pathList = list;
+                this.getList();
+            },
+            rowClick(row, column, event) {
+                if (row.isFolder==1) {
+                    //进入子目录
+                    this.parentFid = row.id;
+                    this.pathList.push(row);
+                    this.getList();
+                } else {
+                    //直接查看,在线打开
+                }
+            },
+            addFolder() {
+                this.$refs.form2.validate(valid => {
+                    if (valid) {
+                        this.http.post('/document/createDocument', this.folderForm,
+                            res => {
+                                if (res.code == "ok") {
+                                    this.addFolderDialog = false;
+                                    this.getRecentList();
+                                    this.getList();
+                                } else {
+                                    this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                    });
+                                }
+                            },
+                            error => {
+                                this.$message({
+                                    message: error,
+                                    type: "error"
+                                });
+                            });
+                    }
+                });
+                
+            },
+            showEditName(row) {
+                this.addFolderDialog = true;
+                this.folderForm = JSON.parse(JSON.stringify(row));
+            },
+            createFolder(){
+                this.addFolderDialog = true;
+                this.folderForm = {projectId: this.curProjectId, folderId: this.parentFid,isFolder: 1};
+            },
+
+            openWin(url) {
+                var el = document.createElement("a");
+                document.body.appendChild(el);
+                el.href = encodeURI(url); 
+                el.target = '_blank'; 
+                el.click();
+                document.body.removeChild(el);
+            },
+
+            downloadByA(row) {
+                const a = document.createElement('a'); // 创建a标签
+                a.setAttribute('download', row.documentName);// download属性
+                a.setAttribute('href', row.url);// href链接
+                a.click();// 自执行点击事件
+                a.remove();
+            },
+
+            //上传
+            uploadFile(params) {
+                this.upLoading = true;
+                var fileObj = params.file;
+                var form = new FormData();
+                form.append("projectId",this.curProjectId);
+                form.append("file", fileObj);
+                if (this.parentFid != null) {
+                    form.append("folderId", this.parentFid);
+                }
+                this.http.uploadFile('/document/uploadDocument', form , res => {
+                    this.upLoading = false;
+                    this.$refs.upload.clearFiles();
+                    if (res.code == "ok") {
+                        this.$message({
+                            message: "上传成功",
+                            type: 'success'
+                        });
+                        this.getList();
+                        this.getRecentList();
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.upLoading = false;
+                    this.$refs.upload.clearFiles();
+                    this.$message({
+                        message: error,
+                        type: 'error'
+                    });
+                })
+            },
+
+            //下载
+            dowloadFile(row) {
+                this.http.post(this.port.project.dowloadFile, {
+                    id: row.id
+                } , res => {
+                    this.getOperList();
+                }, error => {
+                })
+            },
+
+
+            //获取近期文件
+            getRecentList() {
+                this.http.post('/document/recentlyList', {
+                    projectId: this.curProjectId,
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.recentFiles = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            getUsers() {
+                this.http.post(this.port.manage.list, {
+                    departmentId: -1,
+                    pageIndex: 1,
+                    pageSize: 99999
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.users = res.data.records;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+
+
+            //获取列表
+            getList() {
+                this.listLoading = true;
+                this.http.post('/document/allList', {
+                    projectId: this.curProjectId,
+                    parentFid: this.parentFid
+                },
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        this.list = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            refreshPage() {
+                this.curProjectId = parseInt(this.$route.params.id);
+                this.getRecentList();
+                this.getList();
+            }
+        },
+        created() {
+            console.log('created===');
+            let height = window.innerHeight;
+            this.tableHeight = height - 190;
+            const that = this;
+            window.onresize = function temp() {
+                that.tableHeight = window.innerHeight - 190;
+            };
+        },
+        mounted() {
+            console.log('mounted===');
+            this.curProjectId = parseInt(this.$route.params.id);
+            this.getRecentList();
+            this.getList();
+            this.getUsers();
+        }
+    };
+</script>

+ 650 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/project/info.vue

@@ -0,0 +1,650 @@
+<template>
+        <div :style="'padding:20px 50px;background:#f7f7f7;min-height:'+tableHeight+'px;'">
+        <div style="margin: 0 auto;width:900px;">
+            <el-row :gutter="20">
+            <el-col :span="16" >
+                <div class="box info">
+                    <label>基本信息<el-link v-if="user.id == project.creatorId || user.id == project.inchargerId" @click="showEdit" style="float:right;"><i class="el-icon-edit"  ></i></el-link></label>
+                    <el-row :gutter="10" >
+                        <el-col :span="5" ><span class="gray_label">项目名称:</span></el-col><el-col :span="19" ><span >{{project.projectName}}</span></el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                        <el-col :span="5" ><span class="gray_label">状态:</span></el-col><el-col :span="7" ><span >{{statusTxt[project.status]}}</span></el-col>
+                        <el-col :span="5" ><span class="gray_label">完成度: </span></el-col><el-col :span="7" ><span>
+                            <el-progress :percentage="project.progress"></el-progress></span></el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                        <el-col :span="5" ><span class="gray_label">项目编码: </span></el-col><el-col :span="7" ><span >{{project.projectCode}}</span></el-col>
+                        <el-col :span="5" ><span class="gray_label">项目预算:</span></el-col><el-col :span="7" >
+                        <span >{{project.budget == null?'-':project.budget}} 元</span></el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                        <el-col :span="5" ><span class="gray_label">项目级别: </span></el-col><el-col :span="7" ><span >{{levelTxt[project.level]}}</span></el-col>
+                        <el-col :span="5" ><span class="gray_label">创建日期:</span></el-col><el-col :span="7" ><span>{{project.createDate}}</span></el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                        <el-col :span="5" ><span class="gray_label">计划开始日期:</span></el-col><el-col :span="7" >
+                            <span >{{project.planStartDate==null?'-':project.planStartDate}}</span></el-col>
+                        <el-col :span="5" ><span class="gray_label">计划结束日期:</span></el-col><el-col :span="7" ><span>
+                            {{project.planEndDate == null?'-':project.planEndDate}}</span></el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                        <el-col :span="5" ><span class="gray_label">实际完成日期:</span></el-col><el-col :span="7" ><span>
+                            {{project.finishDate==null?'-':project.finishDate}}</span></el-col>
+                    </el-row>
+                </div>
+
+                <div class="box" style="margin-top:10px;">
+                    <div><label>相关人员</label>
+                    <el-link v-if="user.id == project.creatorId || user.id == project.inchargerId" @click="showEditPar" style="float:right;"><i class="el-icon-edit"  ></i></el-link>
+                    </div>
+                    <div style="margin-top:10px;color:#999;">负责人</div>
+                    <div><el-link style="margin:10px" @click="showUser(project.inchargerId)">{{project.inchargerName}}</el-link></div>
+                    <div style="color:#999;">参与人</div>
+                    <div>
+                        <el-link v-for="item in project.participationList" :key="item.id" style="margin:10px;" @click="showUser(item.id)">{{item.name}}</el-link>
+                        <el-button class="el-icon-plus" @click="addMembVisible=true" size="mini"></el-button>
+                    </div>
+                </div>
+                <div class="box" style="margin-top:10px;">
+                    <label>项目统计</label>
+                    <div>
+                        <el-row :gutter="10">
+                        <el-col :span="4" style="text-align:center;">
+                            <p style="color:#666;font-size:12px;">已完成</p>
+                            <p style="font-size:20px;font-weight:bold;color:green;">{{taskSum.finishCount}}</p>
+                        </el-col>
+                        <el-col :span="4" style="text-align:center;">
+                            <p style="color:#666;font-size:12px;">未完成</p>
+                            <p style="font-size:20px;color:blue;font-weight:bold;">{{taskSum.unfinishCount}}</p>
+                        </el-col>
+                        <el-col :span="4" style="text-align:center;">
+                            <p style="color:#666;font-size:12px;">已逾期</p>
+                            <p style="font-size:20px;color:red;font-weight:bold;">{{taskSum.timeupCount}}</p>
+                        </el-col>
+                        <el-col :span="4" style="text-align:center;">
+                            <p style="color:#666;font-size:12px;">待认领</p>
+                            <p style="font-size:20px;color:#orange;font-weight:bold;">{{taskSum.unassignCount}}</p>
+                        </el-col>
+                        <el-col :span="4" style="text-align:center;">
+                            <p style="color:#666;font-size:12px;">今日到期</p>
+                            <p style="font-size:20px;font-weight:bold;color:pink;">{{taskSum.todayTimeupCount}}</p>
+                        </el-col>
+                        <el-col :span="4" style="text-align:center;">
+                            <p style="color:#666;font-size:12px;">逾期完成</p>
+                            <p style="font-size:20px;font-weight:bold;color:gray;">{{taskSum.timeupFinishCount}}</p>
+                        </el-col>
+                        </el-row>
+                    </div>
+                </div>
+            </el-col>
+            <el-col :span="8" style="background:#fff;border: 1px solid #eeeeee;border-radius:5px;min-height:547px;">
+                <div>
+                    <p><i class="el-icon-trophy"></i><span style="margin-left:5px;">里程碑</span></p>
+                </div>
+                <div>
+                <el-timeline :reverse="reverse" style="padding-left: 3px;">
+                    <el-timeline-item
+                    v-for="(task, index) in mileStoneList"
+                    :key="index"
+                    :color="task.taskStatus==0?'#ddd':'#830BE2'"
+                    size="large"
+                    :timestamp="task.endDate">
+                    {{task.name}}
+                    </el-timeline-item>
+                </el-timeline>
+                </div>
+            </el-col>
+            </el-row>
+        </div>
+        <!--用户详细信息弹出框-->
+        <el-dialog title="查看详情" v-if="userDetailVisible" :visible.sync="userDetailVisible" :close-on-click-modal="false" customClass="customWidth" width="400px">
+            <div class="line"><span>姓名</span><span>{{userDetail.name}}</span></div>
+            <div class="line"><span>手机号码</span><span>{{userDetail.phone}}</span></div>
+            <div class="line"><span>部门</span><span>{{userDetail.departmentName}}</span></div>
+            <div class="line" v-if="user.role==1||user.role==2"><span>成本</span><span>{{userDetail.cost}}元/小时</span></div>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="userDetailVisible = false" >确定</el-button>
+            </div>
+        </el-dialog>
+
+        
+        <!--编辑基本信息界面-->
+        <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
+            <el-form ref="basicInfoForm" :model="addForm" :rules="rules" label-width="120px">
+                <el-form-item label="项目编号" >
+                    <el-input v-model="addForm.code"  placeholder="请输入项目编号" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="项目名称" prop="name">
+                    <el-input v-model="addForm.name"  placeholder="请输入项目名称" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="级别" >
+                    <el-select v-model="addForm.level"  placeholder="请选择级别" style="width:32%;" >
+                        <el-option v-for="item in importanceList" :key="item.id" :label="item.label" :value="item.id"></el-option>
+                    </el-select>
+                    <span style="margin-left:50px;margin-right:10px;">项目预算</span>
+                    <el-input v-model="addForm.budget"    style="width:32%;"
+                    placeholder="整数" clearable @keyup.native="number"></el-input><span style="margin-left:10px;">元</span>
+                </el-form-item>
+                <el-form-item label="开始日期" prop="planStartDate">
+                    <el-date-picker v-model="addForm.planStartDate" 
+                     :editable="false" 
+                     format="yyyy-MM-dd" 
+                     value-format="yyyy-MM-dd"
+                     :clearable="false" type="date" 
+                     placeholder="选择日期"></el-date-picker>
+                </el-form-item>
+                <el-form-item label="截止日期" prop="planEndDate">
+                    <el-date-picker v-model="addForm.planEndDate" 
+                     :editable="false" 
+                     format="yyyy-MM-dd" 
+                     value-format="yyyy-MM-dd"
+                     :clearable="false" type="date" 
+                     placeholder="选择日期"></el-date-picker>
+                </el-form-item>
+               
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="addFormVisible = false">取消</el-button>
+                <el-button type="primary" @click="submitInsert" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+
+        <!--编辑参与人界面-->
+        <el-dialog :title="title" v-if="pVisible" :visible.sync="pVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
+            <el-form ref="participForm" :model="addForm" :rules="rules" label-width="120px">
+                <el-form-item label="全部参与者">
+                    <el-select v-model="addForm.userId" multiple filterable placeholder="请选择参与者" style="width:100%;" @change="changeParticipator">
+                        <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="主要负责人" >
+                    <el-select v-model="addForm.inchargerId"  filterable placeholder="请选择负责人" style="width:100%;" >
+                        <el-option v-for="item in project.participationList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="pVisible = false">取消</el-button>
+                <el-button type="primary" @click="submitParticip" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+
+        <!--添加参与人界面-->
+        <el-dialog title="添加参与人" v-if="addMembVisible" :visible.sync="addMembVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
+            <el-form ref="addMembForm" :model="addMembForm"  label-width="120px">
+                <el-form-item label="新增参与者">
+                    <el-select v-model="addMembForm.userId" multiple filterable placeholder="请选择参与者" style="width:100%;" >
+                        <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="addMembVisible = false">取消</el-button>
+                <el-button type="primary" @click="submitAddMemb" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<style scoped>
+.fileTypeIcon {
+    color:#20a0ff;font-size:20px;
+
+}
+.box {
+    background:#fff;border: 1px solid #eeeeee;border-radius:5px;padding:10px;
+}
+.info span {
+    color:#303133;
+}
+.gray_label {
+    color:#999 !important;
+}
+
+.el-row {
+    margin-top:10px;
+}
+.line {
+    padding:10px;
+}
+.line span{
+    font-size:15px;
+}
+.line span:nth-child(even){
+    float:right;
+}
+</style>
+<script>
+    import util from "../../common/js/util";
+    export default {
+        data() {
+            return {
+                addMembVisible:false,
+                addMembForm:{},
+                pVisible:false,
+                taskSum:{},
+                participator:[],
+                users:[],
+                addForm:{},
+                addFormVisible:false,
+                userDetail:{},
+                userDetailVisible: false,
+                importanceList:[{id:1,label:'一般'},{id:2,label:'紧急'},{id:3,label:'重要'},{id:4,label:'重要且紧急'}],
+                //1-一般,2-紧急,3-重要,4-重要且紧急
+                levelTxt:["全部","一般","紧急","重要","重要且紧急"],
+                //1-进行中,2-已完成,3-已撤销
+                statusTxt: ["全部","进行中","已完成","已撤销"],
+                mileStoneList:[],
+                reverse:false,
+                project:{},
+                addFolderDialog: false,
+                upLoading:false,
+                keyword:null,
+                user: JSON.parse(sessionStorage.getItem("user")),
+                recentFiles: [],
+                addLoading: false,
+                curProjectId:null,
+                title: "",
+                rules: {
+                    name: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
+                }
+            };
+        },
+        methods: {
+            //提交添加参与人的请求
+            submitAddMemb() {
+                this.addLoading = true;
+                let formData = new FormData();
+                formData.append("id", this.curProjectId);
+                if(this.addMembForm.userId.length != 0) {
+                    for(var j in this.addMembForm.userId) {
+                        formData.append("userId", this.addMembForm.userId[j]);
+                    }
+                }
+                this.http.uploadFile('/project/addMemb',formData,
+                res => {
+                    this.addLoading = false;
+                    if (res.code == "ok") {
+                        this.$message({
+                            message: "添加成功",
+                            type: "success"
+                        });
+                        this.addMembVisible = false;
+                        this.getProjectInfo();
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.addLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            editTask(task) {
+                // this.addForm = JSON.parse(JSON.stringify(task));
+                this.addFormVisible = true;
+                this.addLoading = false;
+                this.title = "编辑任务";
+                this.getTaskDetail(task.id);
+            },
+            getProjectTaskSum() {
+                this.http.post('/project/taskSum', {
+                    id: this.curProjectId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.taskSum = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            number(){  
+             this.addForm.budget = this.addForm.budget.replace(/[^\.\d]/g,'');
+                this.addForm.budget = this.addForm.budget.replace('.','');
+          },
+            //选择参与人
+            changeParticipator() {
+                //检查是否在参与人中,如果没有需要加入到参与人中
+                console.log(this.addForm.userId);
+                var find = false;
+                this.project.participationList = [];
+                this.addForm.userId.forEach(u=>{
+                    var findUser = this.users.filter(au=>au.id == u)[0];
+                    this.project.participationList.push(findUser);
+                })
+                
+            },
+            getUsers() {
+                this.http.post(this.port.manage.list, {
+                    departmentId: -1,
+                    pageIndex: 1,
+                    pageSize: 99999
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.users = res.data.records;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            submitParticip() {
+                this.addLoading = true;
+                let formData = new FormData();
+                if(this.addForm.id != null) {
+                    formData.append("id", this.addForm.id);
+                }
+                formData.append("name", this.addForm.name);
+                if(this.addForm.userId.length != 0) {
+                    for(var j in this.addForm.userId) {
+                        formData.append("userId", this.addForm.userId[j]);
+                    }
+                }
+                if(this.addForm.inchargerId != null) {
+                    formData.append("inchargerId", this.addForm.inchargerId);
+                }
+                
+                this.http.uploadFile(this.port.project.add,formData,
+                res => {
+                    this.addLoading = false;
+                    if (res.code == "ok") {
+                        this.$message({
+                            message: '修改成功',
+                            type: "success"
+                        });
+                        this.pVisible = false;
+                        this.getProjectInfo();
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.addLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            submitInsert() {
+                this.$refs.basicInfoForm.validate(valid => {
+                    if (valid) {
+                        this.addLoading = true;
+                        let formData = new FormData();
+                        formData.append("name", this.addForm.name);
+                        if(this.addForm.id != null) {
+                            formData.append("id", this.addForm.id);
+                        }
+                        if(this.addForm.userId.length != 0) {
+                            for(var j in this.addForm.userId) {
+                                formData.append("userId", this.addForm.userId[j]);
+                            }
+                        }
+                        if(this.addForm.inchargerId != null) {
+                            formData.append("inchargerId", this.addForm.inchargerId);
+                        }
+                        if(this.addForm.code != null) {
+                            formData.append("code", this.addForm.code);
+                        }
+                        if(this.addForm.planStartDate != null) {
+                            formData.append("planStartDate", this.addForm.planStartDate);
+                        }
+                        if(this.addForm.planEndDate != null) {
+                            formData.append("planEndDate", this.addForm.planEndDate);
+                        }
+                        if(this.addForm.level != null) {
+                            formData.append("level", this.addForm.level);
+                        }
+                        if(this.addForm.budget != null) {
+                            formData.append("budget", this.addForm.budget);
+                        }
+                        
+                        this.http.uploadFile(this.port.project.add,formData,
+                        res => {
+                            this.addLoading = false;
+                            if (res.code == "ok") {
+                                this.$message({
+                                    message: this.addForm.id!=null?'修改':'创建'+"成功",
+                                    type: "success"
+                                });
+                                this.addFormVisible = false;
+                                this.getProjectInfo();
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.addLoading = false;
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                        });
+                        }
+                });
+            },
+            showEdit() {
+                this.addForm = JSON.parse(JSON.stringify(this.project));
+                console.log('---'+this.addForm);
+                console.log(this.addForm.projectCode);
+                
+                var list = this.project.participationList , arr = [];
+                for(var j in list) {
+                    arr.push(list[j].id)
+                }
+                this.addForm.userId = arr;
+                this.addForm.code = this.addForm.projectCode;
+                this.addForm.name = this.addForm.projectName;
+                this.addFormVisible = true;
+
+            },
+            showEditPar() {
+                this.addForm = JSON.parse(JSON.stringify(this.project));
+                this.addForm.code = this.addForm.projectCode;
+                this.addForm.name = this.addForm.projectName;
+                //设置参与人
+                var list = this.project.participationList , arr = [];
+                for(var j in list) {
+                    arr.push(list[j].id)
+                }
+                this.addForm.userId = arr;
+                console.log(this.addForm.userId );
+
+                this.pVisible = true;
+                
+            },
+            //显示用户详情
+            showUser(userId) {
+                this.userDetailVisible = true;
+                this.http.post(this.port.manage.userDetail, {
+                    userId: userId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.userDetail = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            cursorOver(row, column, cell, event) {
+                this.currentDataId = row.id;
+            },
+            viewOnline(row) {
+                this.http.post('/pdf-file/getProjectFile', {fileId: row.id},
+                res => {
+                    if (res.code == "ok") {
+                        console.log(res.data+'----'+row.documentName);
+                        let routeUrl = this.$router.resolve({
+                            path: "/viewonline",
+                            params: {serverFname:res.data, fileName:row.documentName}
+                        });
+                        sessionStorage.setItem("serverFname",res.data);
+                        sessionStorage.setItem("fileName",row.documentName);
+                        console.log(routeUrl.href);
+                        window.open(routeUrl.href, '_blank');
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error,
+                        type: 'error'
+                    });
+                })
+            },
+            
+
+            openWin(url) {
+                var el = document.createElement("a");
+                document.body.appendChild(el);
+                el.href = encodeURI(url); 
+                el.target = '_blank'; 
+                el.click();
+                document.body.removeChild(el);
+            },
+
+            //获取里程碑文件
+            getMileStoneList() {
+                this.http.post('/task/getMileStoneList', {
+                    projectId: this.curProjectId,
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.mileStoneList = res.data;
+                        this.mileStoneList.unshift( {id:-1, name:'开始', taskStatus:1});
+                        
+                        
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            getUsers() {
+                this.http.post(this.port.manage.list, {
+                    departmentId: -1,
+                    pageIndex: 1,
+                    pageSize: 99999
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.users = res.data.records;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+
+
+            //获取列表
+            getProjectInfo() {
+                this.listLoading = true;
+                this.http.post('/project/detail', {
+                    id: this.curProjectId
+                },
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        this.project = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            refreshPage() {
+                this.curProjectId = parseInt(this.$route.params.id);
+                this.getMileStoneList();
+                this.getProjectInfo();
+                this.getProjectTaskSum();
+            }
+        },
+        created() {
+            console.log('created===');
+            let height = window.innerHeight;
+            this.tableHeight = height - 160;
+            const that = this;
+            window.onresize = function temp() {
+                that.tableHeight = window.innerHeight - 160;
+            };
+        },
+        mounted() {
+            console.log('mounted===');
+            this.curProjectId = parseInt(this.$route.params.id);
+            this.getMileStoneList();
+            this.getProjectInfo();
+            this.getUsers();
+            this.getProjectTaskSum();
+        }
+    };
+</script>

Разница между файлами не показана из-за своего большого размера
+ 1453 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue


+ 411 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/project/summary.vue

@@ -0,0 +1,411 @@
+<template>
+        <div :style="'padding:10px;background:#f7f7f7;min-height:'+tableHeight+'px;'">
+        <div style="margin: 0 auto;width:1120px;">
+            <!-- <label>项目统计</label> -->
+            <el-row :gutter="10">
+            <!-- 任务数量总计 -->
+            <el-col :span="12">    
+            <div class="box">
+                <div >
+                    <div class="lableTxt">项目概览表</div>
+                    <el-divider></el-divider>
+                    <el-row :gutter="10">
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">全部</p>
+                        <p style="font-size:28px;font-weight:bold;color:black;">{{taskSum.total}}</p>
+                    </el-col>    
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">已完成</p>
+                        <p style="font-size:28px;font-weight:bold;color:green;">{{taskSum.finishCount}}</p>
+                    </el-col>
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">未完成</p>
+                        <p style="font-size:28px;color:blue;font-weight:bold;">{{taskSum.unfinishCount}}</p>
+                    </el-col>
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">已逾期</p>
+                        <p style="font-size:28px;color:red;font-weight:bold;">{{taskSum.timeupCount}}</p>
+                    </el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">待认领</p>
+                        <p style="font-size:28px;color:#orange;font-weight:bold;">{{taskSum.unassignCount}}</p>
+                    </el-col>
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">今日到期</p>
+                        <p style="font-size:28px;font-weight:bold;color:pink;">{{taskSum.todayTimeupCount}}</p>
+                    </el-col>
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">逾期完成</p>
+                        <p style="font-size:28px;font-weight:bold;color:gray;">{{taskSum.timeupFinishCount}}</p>
+                    </el-col>
+                    <el-col :span="6" style="text-align:center;">
+                        <p style="color:#666;font-size:12px;">时间待定</p>
+                        <p style="font-size:28px;font-weight:bold;color:black;">{{taskSum.timeunsetCount}}</p>
+                    </el-col>
+                    </el-row>
+                </div>
+            </div>
+            </el-col>
+            <el-col :span="12">    
+                <div class="box">   
+                    <div class="lableTxt">执行人分配</div>
+                    <el-divider></el-divider>
+                    <div id="executorPanel" style="height:300px;"></div>
+                </div>
+            </el-col>
+            </el-row>
+            <el-row :gutter="10">
+                <el-col :span="12">    
+                    <div class="box">   
+                        <div class="lableTxt">耗时最多任务</div>
+                        <el-divider></el-divider>
+                        <div id="costPanel" style="height:300px;"></div>
+                    </div>
+                </el-col>
+                <el-col :span="12">    
+                    <div class="box">   
+                        <div class="lableTxt">按任务列表统计</div>
+                        <el-divider></el-divider>
+                        <div id="stagesPanel" style="height:300px;"></div>
+                    </div>
+                </el-col>
+            </el-row>
+        </div>
+        
+    </div>
+</template>
+<style scoped>
+#executorPanel {
+        display: inline-block;
+        width: 100%; 
+    }  
+.el-divider--horizontal {
+    margin: 10px 0;
+    height: 0.5px;
+}
+.box {
+    background:#fff;border: 1px solid #eeeeee;border-radius:5px;padding:10px;
+    height:303.7px;margin-top:10px;
+}
+.info span {
+    color:#303133;
+}
+.gray_label {
+    color:#999 !important;
+}
+
+.el-row {
+    margin-top:10px;
+}
+.lableTxt {
+    color:#666;
+}
+
+</style>
+<script>
+    import util from "../../common/js/util";
+    export default {
+        data() {
+            return {
+                costChart:null,
+                stagesChart: null,
+                executorChart: null,
+                pVisible:false,
+                taskSum:{},
+                users:[],
+                importanceList:[{id:1,label:'一般'},{id:2,label:'紧急'},{id:3,label:'重要'},{id:4,label:'重要且紧急'}],
+                //1-一般,2-紧急,3-重要,4-重要且紧急
+                levelTxt:["全部","一般","紧急","重要","重要且紧急"],
+                //1-进行中,2-已完成,3-已撤销
+                statusTxt: ["全部","进行中","已完成","已撤销"],
+                addFolderDialog: false,
+                upLoading:false,
+                user: JSON.parse(sessionStorage.getItem("user")),
+                addLoading: false,
+                curProjectId:null,
+                title: "",
+                
+            };
+        },
+        methods: {
+            getTopCostTask() {
+                let _this = this;
+                this.http.post('/task/getTopCostTask', {projectId: this.curProjectId},
+                res => {
+                    if (res.code == "ok") {
+                        var xList = [], yList = [], list = res.data;
+                        for(var i in list) {
+                            xList.push(list[i].name.length>6?list[i].name.substring(0,6)+'..':list[i].name);
+                            yList.push({
+                                "value": list[i].value,
+                                "id": list[i].id,
+                                "fullName":list[i].name,
+                            });
+                        }
+                        var myChart = echarts.init(document.getElementById("costPanel"));
+                        _this.costChart = myChart;
+                        var option = {
+                            title: {
+                                show:list.length == 0,
+                                textStyle: {
+                                    color: "#666666",
+                                    fontSize: 18,
+                                    fontWeight: 'normal',
+                                 },
+                              text: list.length == 0?"暂无数据":"耗时最多任务图",
+                              left: "center",
+                              top: "center"
+                            },
+                            toolbox: {
+                                show: true,
+                                feature:{
+                                    saveAsImage:{
+                                        show:true
+                                    },
+                                    restore:{
+                                        show:true
+                                    },
+                                    magicType:{
+                                        type:['line','bar']
+                                    },
+                                }
+                            },
+                            tooltip:{
+                                trigger:'axis',
+                                formatter: function (params,ticket,callback) {
+                                    var res = params[0].data.fullName + ""+" : " + params[0].data.value 
+                                    + "小时";
+                                    _this.params = params;
+                                    return res;
+                                }
+                            },
+                            xAxis: {
+                                data: xList,
+                                axisLabel: {
+                                    interval:0,rotate:20
+                                }
+                            },
+                            yAxis: [{
+                                type : 'value',
+                                axisLabel: {
+                                    formatter:'{value} 小时'
+                                }
+                            }],
+                            series: [{
+                                name: '耗时(小时)',
+                                type: 'bar',
+                                barMaxWidth: 30,
+                                data: yList,
+                            }]
+                        };
+                        myChart.setOption(option);
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            getStagesPanel(){
+                let _this = this;
+                this.http.post('/task/getStagesPanel', {projectId: this.curProjectId},
+                res => {
+                    if (res.code == "ok") {
+                        var list = res.data;
+                        var myChart = echarts.init(document.getElementById("stagesPanel"));
+                        _this.stagesChart = myChart;
+                        myChart.setOption({
+                            title: {
+                                show:list.length == 0,
+                                textStyle: {
+                                    color: "#666666",
+                                    fontSize: 18,
+                                    fontWeight: 'normal',
+                                 },
+                              text: list.length == 0?"暂无数据":"任务列表统计",
+                              left: "center",
+                              top: "center"
+                            },
+                            toolbox: {
+                                show: true,
+                                feature:{
+                                    saveAsImage:{
+                                        show:true
+                                    },
+                                }
+                            },
+                            tooltip:{
+                                trigger:'item',
+                                formatter: "{b}<br/>任务数:{c} ({d}%)",
+                            },
+                            series : [
+                                {
+                                    name: '任务列表',
+                                    type: 'pie',
+                                    radius: '55%',
+                                    data:list
+                                }
+                            ]
+                        })
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            getExecutorPanel(){
+                let _this = this;
+                this.http.post('/task/getExecutorPanel', {projectId: this.curProjectId},
+                res => {
+                    if (res.code == "ok") {
+                        var xList = [], yList = [], list = res.data;
+                        for(var i in list) {
+                            xList.push(list[i].executorName);
+                            yList.push({
+                                "value": list[i].taskCount,
+                                "id": list[i].executorId
+                            });
+                        }
+                        var myChart = echarts.init(document.getElementById("executorPanel"));
+                        _this.executorChart = myChart;
+                        var option = {
+                            title: {
+                                show:list.length == 0,
+                                textStyle: {
+                                    color: "#666666",
+                                    fontSize: 18,
+                                    fontWeight: 'normal',
+                                 },
+                              text: list.length == 0?"暂无数据":"执行人分配图",
+                              left: "center",
+                              top: "center"
+                            },
+                            toolbox: {
+                                show: true,
+                                feature:{
+                                    saveAsImage:{
+                                        show:true
+                                    },
+                                    restore:{
+                                        show:true
+                                    },
+                                    magicType:{
+                                        type:['line','bar']
+                                    },
+                                }
+                            },
+                            tooltip:{
+                                trigger:'axis',
+                                formatter: function (params,ticket,callback) {
+                                    var res = params[0].name + ""+" : " + params[0].data.value 
+                                    + "个";
+                                    _this.params = params;
+                                    return res;
+                                }
+                            },
+                            xAxis: {
+                                data: xList,
+                                axisLabel: {
+                                    interval:0,rotate:20
+                                }
+                            },
+                            yAxis: [{
+                                type : 'value',
+                                axisLabel: {
+                                    formatter:'{value} '
+                                }
+                            }],
+                            series: [{
+                                name: '任务数量(个)',
+                                type: 'bar',
+                                barMaxWidth: 30,
+                                data: yList,
+                            }]
+                        };
+                        myChart.setOption(option);
+                        console.log('===这是完成');
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            getProjectTaskSum() {
+                this.http.post('/project/taskSum', {
+                    id: this.curProjectId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.taskSum = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            refreshPage() {
+                this.curProjectId = parseInt(this.$route.params.id);
+                this.getProjectTaskSum();
+                this.getExecutorPanel();
+                this.getTopCostTask();
+                this.getStagesPanel();
+            }
+        },
+        created() {
+            console.log('created===');
+            let height = window.innerHeight;
+            this.tableHeight = height - 160;
+            const that = this;
+            window.onresize = function temp() {
+                that.tableHeight = window.innerHeight - 160;
+            };
+        },
+        mounted() {
+            console.log('=========图表mounted===');
+            this.curProjectId = parseInt(this.$route.params.id);
+            var _this = this;
+            window.addEventListener("resize", function() {
+                _this.executorChart.resize();
+                _this.stagesChart.resize();
+                _this.costChart.resize();
+            });
+            this.getProjectTaskSum();
+                this.getExecutorPanel();
+                this.getStagesPanel();
+                this.getTopCostTask();
+        }
+    };
+</script>

+ 549 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/task/list.vue

@@ -0,0 +1,549 @@
+<template>
+    <section>
+        <!--工具条-->
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true">
+                <el-form-item label="任务列表">
+                    
+                </el-form-item>
+                <el-form-item >
+                    <div>
+                    <el-input style="float:left;" v-model="keyword" class="input-with-select" placeholder="请输入项目名称关键字" clearable="true">
+                        <el-select v-model="searchField" style="width:120px;"  slot="prepend" placeholder="请选择">
+                            <el-option label="项目名称" value=1 ></el-option>
+                            <el-option label="项目编码" value=2></el-option>
+                        </el-select>
+                        <el-button slot="append" @click="searchList" icon="el-icon-search"></el-button>
+                    </el-input>
+                    </div>
+                </el-form-item>
+                <el-form-item style="float:right;">
+                    <el-link type="primary" :underline="false" @click="handleAdd(-1,null)">新增项目</el-link>
+                </el-form-item>
+            </el-form>
+        </el-col>
+
+        <!--列表-->
+        <el-table :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+            <el-table-column type="index" width="60">
+                <template slot-scope="scope" >
+                        {{scope.$index+1+(page-1)*size}}
+                    </template>
+            </el-table-column>
+            <el-table-column prop="projectCode" label="项目编码" sortable width="150"></el-table-column>
+            <el-table-column prop="projectName" label="项目名称" sortable></el-table-column>
+            <el-table-column prop="inchargerName" label="负责人" sortable width="150">
+                <template slot-scope="scope">
+                    <el-link type="primary" @click="showUser(scope.row.inchargerId)">{{scope.row.inchargerName}}</el-link>
+                </template>
+            </el-table-column>
+            <el-table-column prop="participator" label="参与者" sortable>
+                
+                <template slot-scope="scope">
+                    <v-for v-for="par in scope.row.participator" :key="par.id" >
+                        <el-link style="margin-right:10px;" type="primary" @click="showUser(par.id)">{{par.name}}</el-link>
+                    </v-for>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" width="290">
+                <template slot-scope="scope">
+                    <el-button v-if="user.role>0" size="small" type="primary" @click="subProject(scope.row)">子项目</el-button>
+                    <el-button size="small" type="primary" @click="handleAdd(scope.$index, scope.row)">编辑</el-button>
+                    <el-button v-if="user.role>0" size="small" type="danger" @click="deletePro(scope.$index, scope.row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!--工具条-->
+        <el-col :span="24" class="toolbar">
+            <el-pagination
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :page-sizes="[20 , 50 , 80 , 100]"
+                :page-size="20"
+                layout="total, sizes, prev, pager, next"
+                :total="total"
+                style="float:right;"
+            ></el-pagination>
+        </el-col>
+
+        <!--新增界面-->
+        <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
+            <el-form ref="form1" :model="addForm" :rules="rules" label-width="100px">
+                <el-form-item label="项目编号" >
+                    <el-input v-model="addForm.code" :disabled="user.role==0" placeholder="请输入项目编号" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="项目名称" prop="name">
+                    <el-input v-model="addForm.name" :disabled="user.role==0" placeholder="请输入项目名称" clearable></el-input>
+                </el-form-item>
+                <el-form-item label="全部参与者">
+                    <el-select v-model="addForm.userId" multiple filterable placeholder="请选择参与者" style="width:100%;" @change="changeParticipator">
+                        <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="主要负责人" >
+                    <el-select v-model="addForm.inchargerId" :disabled="addForm.userId.length==0 ||  user.role==0" filterable placeholder="请选择负责人" style="width:100%;" @change="changeIncharger">
+                        <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="addFormVisible = false">取消</el-button>
+                <el-button type="primary" @click="submitInsert" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+
+        <!--用户详细信息弹出框-->
+        <el-dialog title="查看详情" v-if="userDetailVisible" :visible.sync="userDetailVisible" :close-on-click-modal="false" customClass="customWidth" width="400px">
+            <div class="line"><span>姓名</span><span>{{userDetail.name}}</span></div>
+            <div class="line"><span>手机号码</span><span>{{userDetail.phone}}</span></div>
+            <div class="line"><span>部门</span><span>{{userDetail.departmentName}}</span></div>
+            <div class="line"><span>成本</span><span>{{userDetail.cost}}元/小时</span></div>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="userDetailVisible = false" >确定</el-button>
+            </div>
+        </el-dialog>
+        <!-- 子项目列表 -->
+        <el-dialog title="子项目列表" show-header="false" v-if="subProjectVisible" :visible.sync="subProjectVisible" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <el-table :data="subProjectList" highlight-current-row  height="400" style="width: 100%;">
+            <el-table-column type="index" width="60" label="序号">
+                <template slot-scope="scope" >
+                        {{scope.$index+1+(page-1)*size}}
+                    </template>
+            </el-table-column>
+            <el-table-column prop="name" label="名称" ></el-table-column>
+            <el-table-column label="操作" width="150">
+                <template slot-scope="scope" >
+                    <el-button size="small" type="primary" @click="addNewSubProject(scope.row)">编辑</el-button>
+                    <el-button size="small" type="danger" @click="deleteSubPro(scope.row)">删除</el-button>
+                </template>
+            </el-table-column>
+
+            </el-table>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="subProjectVisible = false" >关闭</el-button>
+                <el-button type="primary" @click="addNewSubProject()" >新增子项目</el-button>
+            </div>
+        </el-dialog>
+
+
+        <!-- 新增子项目弹出框 -->
+        <el-dialog title="新增/修改子项目" v-if="addSubProject" :visible.sync="addSubProject" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <el-form ref="form2" :model="addForm" :rules="rules" label-width="100px">
+                <el-form-item label="项目名称" prop="name">
+                    <el-input v-model="addForm.name" placeholder="请输入项目名称" clearable></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="addSubProject = false">取消</el-button>
+                <el-button type="primary" @click="submitInsertSubProject" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+    </section>
+</template>
+<style scoped>
+.input-with-select .el-input-group__prepend {
+    background-color: #fff;
+  }
+.line {
+    padding:10px;
+}
+.line span{
+    font-size:18px;
+}
+.line span:nth-child(even){
+    float:right;
+}
+</style>
+<script>
+    import util from "../../common/js/util";
+
+    export default {
+        data() {
+            return {
+                searchField:null,
+                keyword:null,
+                user: JSON.parse(sessionStorage.getItem("user")),
+                userDetailVisible: false,
+                userDetail:{},
+                date: new Date(),
+                users: [],
+                participator:[],
+                tableHeight: 0,
+                listLoading: false,
+                total: 0,
+                page: 1,
+                size: 20,
+                list: [],
+                subProjectVisible: false,
+                subProjectList: [],//子项目列表
+                currentProject:{},
+                addSubProject: false,
+                addFormVisible: false,
+                addLoading: false,
+                title: "",
+                addForm: {
+                    name: '',
+                    userId: [],
+                },
+                rules: {
+                    name: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
+                }
+            };
+        },
+        methods: {
+            deleteSubPro(subProject) {
+                this.$confirm("确定要删除子项目" + subProject.name + "吗?","删除子项目", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                })
+                .then(() => {
+                    this.listLoading = true;
+                    this.http.post('/sub-project/deleteProject',{ 
+                        id: subProject.id 
+                    },
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "删除成功",
+                                type: "success"
+                            });
+                            this.subProject(this.currentProject);
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                })
+                .catch(() => {});
+            },
+            searchList() {
+                this.page = 1;
+                this.getList();
+            },
+            addNewSubProject(subProject) {
+                if (subProject == null) {
+                    this.addForm = {projectId: this.currentProject.id}
+                } else {
+                    this.addForm = subProject;
+                }
+                this.addSubProject = true;
+            },
+            //显示子项目
+            subProject(item) {
+                this.subProjectVisible = true;
+                this.currentProject = item;
+                this.http.post('/sub-project/list', {
+                    projectId: item.id
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.subProjectList = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            //显示用户详情
+            showUser(userId) {
+                this.userDetailVisible = true;
+                this.http.post(this.port.manage.userDetail, {
+                    userId: userId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.userDetail = res.data;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            //选择参与人
+            changeParticipator() {
+                //检查是否在参与人中,如果没有需要加入到参与人中
+                console.log(this.addForm.userId);
+                var find = false;
+                this.participator = [];
+                this.addForm.userId.forEach(u=>{
+                    var findUser = this.users.filter(au=>au.id == u)[0];
+                    this.participator.push(findUser);
+                })
+                
+            },
+            getUsers() {
+                this.http.post(this.port.manage.list, {
+                    departmentId: -1,
+                    pageIndex: 1,
+                    pageSize: 99999
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.users = res.data.records;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+
+            //分页
+            handleCurrentChange(val) {
+                this.page = val;
+                this.getList();
+            },
+
+            handleSizeChange(val) {
+                this.size = val;
+                this.getList();
+            },
+
+            //获取项目列表
+            getList() {
+                this.listLoading = true;
+                this.http.post(this.port.project.listPage, {
+                    pageIndex: this.page,
+                    pageSize: this.size,
+                    keyword:this.keyword,
+                    searchField: this.searchField,
+                },
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        var list = res.data.records;
+                        for(var i in list) {
+                            var participator = list[i].participator , str = "";
+                            for(var j in participator) {
+                                if(j == participator.length-1) {
+                                    str += participator[j].name
+                                } else {
+                                    str += participator[j].name + ','
+                                }
+                            }
+                            list[i].userNames = str;
+                        }
+                        this.list = list;
+                        this.total = res.data.total;
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+
+            //显示新增界面
+            handleAdd(i, item) {
+                if(i == -1) {
+                    this.title = "新增项目";
+                    this.addForm = {
+                        name: '',
+                        userId: [],
+                        code:'',
+                        inchargerId:null,
+                    }
+                } else {
+                    this.title = "修改项目";
+                    var list = item.participator , arr = [];
+                    for(var j in list) {
+                        arr.push(list[j].id)
+                    }
+                    
+                    this.addForm = {
+                        id: item.id,
+                        name: item.projectName,
+                        userId: arr,
+                        code:item.projectCode,
+                        inchargerId: item.inchargerId
+                    }
+                    this.changeParticipator();
+                }
+                this.addFormVisible = true;
+            },
+
+            //提交子项目创建修改请求
+            submitInsertSubProject () {
+                this.$refs.form2.validate(valid => {
+                    if (valid) {
+                        this.http.post('/sub-project/saveOrUpdate',this.addForm,
+                        res => {
+                            if (res.code == "ok") {
+                                this.$message({
+                                    message: "操作成功",
+                                    type: "success"
+                                });
+                                this.subProject(this.currentProject);
+                                this.addSubProject = false;
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.listLoading = false;
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                            }
+                        );
+                        }
+                });
+            },
+            submitInsert() {
+                this.$refs.form1.validate(valid => {
+                    if (valid) {
+                        this.addLoading = true;
+                        let formData = new FormData();
+                        formData.append("name", this.addForm.name);
+                        if(this.addForm.id != null) {
+                            formData.append("id", this.addForm.id);
+                        }
+                        if(this.addForm.userId.length != 0) {
+                            for(var j in this.addForm.userId) {
+                                formData.append("userId", this.addForm.userId[j]);
+                            }
+                        }
+                        if(this.addForm.inchargerId != null) {
+                            formData.append("inchargerId", this.addForm.inchargerId);
+                        }
+                        if(this.addForm.code != null) {
+                            formData.append("code", this.addForm.code);
+                        }
+                        
+                        this.http.uploadFile(this.port.project.add,formData,
+                        res => {
+                            this.addLoading = false;
+                            if (res.code == "ok") {
+                                this.$message({
+                                    message: this.addForm.id!=null?'修改':'创建'+"成功",
+                                    type: "success"
+                                });
+                                this.addFormVisible = false;
+                                this.getList();
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.addLoading = false;
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                        });
+                        }
+                });
+            },
+
+            // 删除
+            deletePro(i, item) {
+                this.$confirm("确定要项目" + item.projectName + "吗?","删除项目", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                })
+                .then(() => {
+                    this.listLoading = true;
+                    this.http.post(this.port.project.delete,{ 
+                        id: item.id 
+                    },
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "删除成功",
+                                type: "success"
+                            });
+                            this.getList();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                })
+                .catch(() => {});
+            },
+
+            detail(i) {
+                this.$router.push("/list/" + this.list[i].id + "/" + this.list[i].projectName);
+            }
+        },
+        created() {
+            let height = window.innerHeight;
+            this.tableHeight = height - 195;
+            const that = this;
+            window.onresize = function temp() {
+                that.tableHeight = window.innerHeight - 195;
+            };
+        },
+        mounted() {
+            this.getList();
+            this.getUsers();
+        }
+    };
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 72 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/dark/content.css

@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+body {
+  background-color: #2f3742;
+  color: #dfe0e4;
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+  line-height: 1.4;
+  margin: 1rem;
+}
+a {
+  color: #4099ff;
+}
+table {
+  border-collapse: collapse;
+}
+/* Apply a default padding if legacy cellpadding attribute is missing */
+table:not([cellpadding]) th,
+table:not([cellpadding]) td {
+  padding: 0.4rem;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-width"]) th,
+table[border]:not([border="0"]):not([style*="border-width"]) td {
+  border-width: 1px;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-style"]) th,
+table[border]:not([border="0"]):not([style*="border-style"]) td {
+  border-style: solid;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-color"]) th,
+table[border]:not([border="0"]):not([style*="border-color"]) td {
+  border-color: #6d737b;
+}
+figure {
+  display: table;
+  margin: 1rem auto;
+}
+figure figcaption {
+  color: #8a8f97;
+  display: block;
+  margin-top: 0.25rem;
+  text-align: center;
+}
+hr {
+  border-color: #6d737b;
+  border-style: solid;
+  border-width: 1px 0 0 0;
+}
+code {
+  background-color: #6d737b;
+  border-radius: 3px;
+  padding: 0.1rem 0.2rem;
+}
+.mce-content-body:not([dir=rtl]) blockquote {
+  border-left: 2px solid #6d737b;
+  margin-left: 1.5rem;
+  padding-left: 1rem;
+}
+.mce-content-body[dir=rtl] blockquote {
+  border-right: 2px solid #6d737b;
+  margin-right: 1.5rem;
+  padding-right: 1rem;
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/dark/content.min.css


+ 67 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/default/content.css

@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+body {
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+  line-height: 1.4;
+  margin: 1rem;
+}
+table {
+  border-collapse: collapse;
+}
+/* Apply a default padding if legacy cellpadding attribute is missing */
+table:not([cellpadding]) th,
+table:not([cellpadding]) td {
+  padding: 0.4rem;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-width"]) th,
+table[border]:not([border="0"]):not([style*="border-width"]) td {
+  border-width: 1px;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-style"]) th,
+table[border]:not([border="0"]):not([style*="border-style"]) td {
+  border-style: solid;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-color"]) th,
+table[border]:not([border="0"]):not([style*="border-color"]) td {
+  border-color: #ccc;
+}
+figure {
+  display: table;
+  margin: 1rem auto;
+}
+figure figcaption {
+  color: #999;
+  display: block;
+  margin-top: 0.25rem;
+  text-align: center;
+}
+hr {
+  border-color: #ccc;
+  border-style: solid;
+  border-width: 1px 0 0 0;
+}
+code {
+  background-color: #e8e8e8;
+  border-radius: 3px;
+  padding: 0.1rem 0.2rem;
+}
+.mce-content-body:not([dir=rtl]) blockquote {
+  border-left: 2px solid #ccc;
+  margin-left: 1.5rem;
+  padding-left: 1rem;
+}
+.mce-content-body[dir=rtl] blockquote {
+  border-right: 2px solid #ccc;
+  margin-right: 1.5rem;
+  padding-right: 1rem;
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/default/content.min.css


+ 72 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/document/content.css

@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+@media screen {
+  html {
+    background: #f4f4f4;
+    min-height: 100%;
+  }
+}
+body {
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+}
+@media screen {
+  body {
+    background-color: #fff;
+    box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
+    box-sizing: border-box;
+    margin: 1rem auto 0;
+    max-width: 820px;
+    min-height: calc(100vh - 1rem);
+    padding: 4rem 6rem 6rem 6rem;
+  }
+}
+table {
+  border-collapse: collapse;
+}
+/* Apply a default padding if legacy cellpadding attribute is missing */
+table:not([cellpadding]) th,
+table:not([cellpadding]) td {
+  padding: 0.4rem;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-width"]) th,
+table[border]:not([border="0"]):not([style*="border-width"]) td {
+  border-width: 1px;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-style"]) th,
+table[border]:not([border="0"]):not([style*="border-style"]) td {
+  border-style: solid;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-color"]) th,
+table[border]:not([border="0"]):not([style*="border-color"]) td {
+  border-color: #ccc;
+}
+figure figcaption {
+  color: #999;
+  margin-top: 0.25rem;
+  text-align: center;
+}
+hr {
+  border-color: #ccc;
+  border-style: solid;
+  border-width: 1px 0 0 0;
+}
+.mce-content-body:not([dir=rtl]) blockquote {
+  border-left: 2px solid #ccc;
+  margin-left: 1.5rem;
+  padding-left: 1rem;
+}
+.mce-content-body[dir=rtl] blockquote {
+  border-right: 2px solid #ccc;
+  margin-right: 1.5rem;
+  padding-right: 1rem;
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/document/content.min.css


+ 68 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/writer/content.css

@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+body {
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+  line-height: 1.4;
+  margin: 1rem auto;
+  max-width: 900px;
+}
+table {
+  border-collapse: collapse;
+}
+/* Apply a default padding if legacy cellpadding attribute is missing */
+table:not([cellpadding]) th,
+table:not([cellpadding]) td {
+  padding: 0.4rem;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-width"]) th,
+table[border]:not([border="0"]):not([style*="border-width"]) td {
+  border-width: 1px;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-style"]) th,
+table[border]:not([border="0"]):not([style*="border-style"]) td {
+  border-style: solid;
+}
+/* Set default table styles if a table has a positive border attribute
+   and no inline css */
+table[border]:not([border="0"]):not([style*="border-color"]) th,
+table[border]:not([border="0"]):not([style*="border-color"]) td {
+  border-color: #ccc;
+}
+figure {
+  display: table;
+  margin: 1rem auto;
+}
+figure figcaption {
+  color: #999;
+  display: block;
+  margin-top: 0.25rem;
+  text-align: center;
+}
+hr {
+  border-color: #ccc;
+  border-style: solid;
+  border-width: 1px 0 0 0;
+}
+code {
+  background-color: #e8e8e8;
+  border-radius: 3px;
+  padding: 0.1rem 0.2rem;
+}
+.mce-content-body:not([dir=rtl]) blockquote {
+  border-left: 2px solid #ccc;
+  margin-left: 1.5rem;
+  padding-left: 1rem;
+}
+.mce-content-body[dir=rtl] blockquote {
+  border-right: 2px solid #ccc;
+  margin-right: 1.5rem;
+  padding-right: 1rem;
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/content/writer/content.min.css


Разница между файлами не показана из-за своего большого размера
+ 714 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.css


Разница между файлами не показана из-за своего большого размера
+ 726 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.inline.css


Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.inline.min.css


Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.min.css


+ 29 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.mobile.css

@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection {
+  /* Note: this file is used inside the content, so isn't part of theming */
+  background-color: green;
+  display: inline-block;
+  opacity: 0.5;
+  position: absolute;
+}
+body {
+  -webkit-text-size-adjust: none;
+}
+body img {
+  /* this is related to the content margin */
+  max-width: 96vw;
+}
+body table img {
+  max-width: 95%;
+}
+body {
+  font-family: sans-serif;
+}
+table {
+  border-collapse: collapse;
+}

+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/content.mobile.min.css

@@ -0,0 +1,7 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse}

BIN
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/fonts/tinymce-mobile.woff


Разница между файлами не показана из-за своего большого размера
+ 3029 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.css


Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.min.css


+ 673 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.mobile.css

@@ -0,0 +1,673 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+/* RESET all the things! */
+.tinymce-mobile-outer-container {
+  all: initial;
+  display: block;
+}
+.tinymce-mobile-outer-container * {
+  border: 0;
+  box-sizing: initial;
+  cursor: inherit;
+  float: none;
+  line-height: 1;
+  margin: 0;
+  outline: 0;
+  padding: 0;
+  -webkit-tap-highlight-color: transparent;
+  /* TBIO-3691, stop the gray flicker on touch. */
+  text-shadow: none;
+  white-space: nowrap;
+}
+.tinymce-mobile-icon-arrow-back::before {
+  content: "\e5cd";
+}
+.tinymce-mobile-icon-image::before {
+  content: "\e412";
+}
+.tinymce-mobile-icon-cancel-circle::before {
+  content: "\e5c9";
+}
+.tinymce-mobile-icon-full-dot::before {
+  content: "\e061";
+}
+.tinymce-mobile-icon-align-center::before {
+  content: "\e234";
+}
+.tinymce-mobile-icon-align-left::before {
+  content: "\e236";
+}
+.tinymce-mobile-icon-align-right::before {
+  content: "\e237";
+}
+.tinymce-mobile-icon-bold::before {
+  content: "\e238";
+}
+.tinymce-mobile-icon-italic::before {
+  content: "\e23f";
+}
+.tinymce-mobile-icon-unordered-list::before {
+  content: "\e241";
+}
+.tinymce-mobile-icon-ordered-list::before {
+  content: "\e242";
+}
+.tinymce-mobile-icon-font-size::before {
+  content: "\e245";
+}
+.tinymce-mobile-icon-underline::before {
+  content: "\e249";
+}
+.tinymce-mobile-icon-link::before {
+  content: "\e157";
+}
+.tinymce-mobile-icon-unlink::before {
+  content: "\eca2";
+}
+.tinymce-mobile-icon-color::before {
+  content: "\e891";
+}
+.tinymce-mobile-icon-previous::before {
+  content: "\e314";
+}
+.tinymce-mobile-icon-next::before {
+  content: "\e315";
+}
+.tinymce-mobile-icon-large-font::before,
+.tinymce-mobile-icon-style-formats::before {
+  content: "\e264";
+}
+.tinymce-mobile-icon-undo::before {
+  content: "\e166";
+}
+.tinymce-mobile-icon-redo::before {
+  content: "\e15a";
+}
+.tinymce-mobile-icon-removeformat::before {
+  content: "\e239";
+}
+.tinymce-mobile-icon-small-font::before {
+  content: "\e906";
+}
+.tinymce-mobile-icon-readonly-back::before,
+.tinymce-mobile-format-matches::after {
+  content: "\e5ca";
+}
+.tinymce-mobile-icon-small-heading::before {
+  content: "small";
+}
+.tinymce-mobile-icon-large-heading::before {
+  content: "large";
+}
+.tinymce-mobile-icon-small-heading::before,
+.tinymce-mobile-icon-large-heading::before {
+  font-family: sans-serif;
+  font-size: 80%;
+}
+.tinymce-mobile-mask-edit-icon::before {
+  content: "\e254";
+}
+.tinymce-mobile-icon-back::before {
+  content: "\e5c4";
+}
+.tinymce-mobile-icon-heading::before {
+  /* TODO: Translate */
+  content: "Headings";
+  font-family: sans-serif;
+  font-size: 80%;
+  font-weight: bold;
+}
+.tinymce-mobile-icon-h1::before {
+  content: "H1";
+  font-weight: bold;
+}
+.tinymce-mobile-icon-h2::before {
+  content: "H2";
+  font-weight: bold;
+}
+.tinymce-mobile-icon-h3::before {
+  content: "H3";
+  font-weight: bold;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  background: rgba(51, 51, 51, 0.5);
+  height: 100%;
+  position: absolute;
+  top: 0;
+  width: 100%;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container {
+  align-items: center;
+  border-radius: 50%;
+  display: flex;
+  flex-direction: column;
+  font-family: sans-serif;
+  font-size: 1em;
+  justify-content: space-between;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .mixin-menu-item {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  border-radius: 50%;
+  height: 2.1em;
+  width: 2.1em;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  flex-direction: column;
+  font-size: 1em;
+}
+@media only screen and (min-device-width:700px) {
+  .tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section {
+    font-size: 1.2em;
+  }
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section .tinymce-mobile-mask-tap-icon {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  border-radius: 50%;
+  height: 2.1em;
+  width: 2.1em;
+  background-color: white;
+  color: #207ab7;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section .tinymce-mobile-mask-tap-icon::before {
+  content: "\e900";
+  font-family: 'tinymce-mobile', sans-serif;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section:not(.tinymce-mobile-mask-tap-icon-selected) .tinymce-mobile-mask-tap-icon {
+  z-index: 2;
+}
+.tinymce-mobile-android-container.tinymce-mobile-android-maximized {
+  background: #ffffff;
+  border: none;
+  bottom: 0;
+  display: flex;
+  flex-direction: column;
+  left: 0;
+  position: fixed;
+  right: 0;
+  top: 0;
+}
+.tinymce-mobile-android-container:not(.tinymce-mobile-android-maximized) {
+  position: relative;
+}
+.tinymce-mobile-android-container .tinymce-mobile-editor-socket {
+  display: flex;
+  flex-grow: 1;
+}
+.tinymce-mobile-android-container .tinymce-mobile-editor-socket iframe {
+  display: flex !important;
+  flex-grow: 1;
+  height: auto !important;
+}
+.tinymce-mobile-android-scroll-reload {
+  overflow: hidden;
+}
+:not(.tinymce-mobile-readonly-mode) > .tinymce-mobile-android-selection-context-toolbar {
+  margin-top: 23px;
+}
+.tinymce-mobile-toolstrip {
+  background: #fff;
+  display: flex;
+  flex: 0 0 auto;
+  z-index: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar {
+  align-items: center;
+  background-color: #fff;
+  border-bottom: 1px solid #cccccc;
+  display: flex;
+  flex: 1;
+  height: 2.5em;
+  width: 100%;
+  /* Make it no larger than the toolstrip, so that it needs to scroll */
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex-shrink: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group > div {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group.tinymce-mobile-exit-container {
+  background: #f44336;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group.tinymce-mobile-toolbar-scrollable-group {
+  flex-grow: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item {
+  padding-left: 0.5em;
+  padding-right: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item.tinymce-mobile-toolbar-button {
+  align-items: center;
+  display: flex;
+  height: 80%;
+  margin-left: 2px;
+  margin-right: 2px;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item.tinymce-mobile-toolbar-button.tinymce-mobile-toolbar-button-selected {
+  background: #c8cbcf;
+  color: #cccccc;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group:first-of-type,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group:last-of-type {
+  background: #207ab7;
+  color: #eceff1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar {
+  /* Note, this file is imported inside .tinymce-mobile-context-toolbar, so that prefix is on everything here. */
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex: 1;
+  padding-bottom: 0.4em;
+  padding-top: 0.4em;
+  /* Make any buttons appearing on the left and right display in the centre (e.g. color edges) */
+  /* For widgets like the colour picker, use the whole height */
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog {
+  display: flex;
+  min-height: 1.5em;
+  overflow: hidden;
+  padding-left: 0;
+  padding-right: 0;
+  position: relative;
+  width: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain {
+  display: flex;
+  height: 100%;
+  transition: left cubic-bezier(0.4, 0, 1, 1) 0.15s;
+  width: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen {
+  display: flex;
+  flex: 0 0 auto;
+  justify-content: space-between;
+  width: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen input {
+  font-family: Sans-serif;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container {
+  display: flex;
+  flex-grow: 1;
+  position: relative;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container .tinymce-mobile-input-container-x {
+  -ms-grid-row-align: center;
+      align-self: center;
+  background: inherit;
+  border: none;
+  border-radius: 50%;
+  color: #888;
+  font-size: 0.6em;
+  font-weight: bold;
+  height: 100%;
+  padding-right: 2px;
+  position: absolute;
+  right: 0;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container.tinymce-mobile-input-container-empty .tinymce-mobile-input-container-x {
+  display: none;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next {
+  align-items: center;
+  display: flex;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next::before {
+  align-items: center;
+  display: flex;
+  font-weight: bold;
+  height: 100%;
+  padding-left: 0.5em;
+  padding-right: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous.tinymce-mobile-toolbar-navigation-disabled::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next.tinymce-mobile-toolbar-navigation-disabled::before {
+  visibility: hidden;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-item {
+  color: #cccccc;
+  font-size: 10px;
+  line-height: 10px;
+  margin: 0 2px;
+  padding-top: 3px;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-item.tinymce-mobile-dot-active {
+  color: #c8cbcf;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-large-font::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-large-heading::before {
+  margin-left: 0.5em;
+  margin-right: 0.9em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-small-font::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-small-heading::before {
+  margin-left: 0.9em;
+  margin-right: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider {
+  display: flex;
+  flex: 1;
+  margin-left: 0;
+  margin-right: 0;
+  padding: 0.28em 0;
+  position: relative;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-size-container {
+  align-items: center;
+  display: flex;
+  flex-grow: 1;
+  height: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-size-container .tinymce-mobile-slider-size-line {
+  background: #cccccc;
+  display: flex;
+  flex: 1;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container {
+  padding-left: 2em;
+  padding-right: 2em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-slider-gradient-container {
+  align-items: center;
+  display: flex;
+  flex-grow: 1;
+  height: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-slider-gradient-container .tinymce-mobile-slider-gradient {
+  background: linear-gradient(to right, hsl(0, 100%, 50%) 0%, hsl(60, 100%, 50%) 17%, hsl(120, 100%, 50%) 33%, hsl(180, 100%, 50%) 50%, hsl(240, 100%, 50%) 67%, hsl(300, 100%, 50%) 83%, hsl(0, 100%, 50%) 100%);
+  display: flex;
+  flex: 1;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-hue-slider-black {
+  /* Not part of theming */
+  background: black;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+  width: 1.2em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-hue-slider-white {
+  /* Not part of theming */
+  background: white;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+  width: 1.2em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-thumb {
+  /* vertically centering trick (margin: auto, top: 0, bottom: 0). On iOS and Safari, if you leave
+     * out these values, then it shows the thumb at the top of the spectrum. This is probably because it is
+     * absolutely positioned with only a left value, and not a top. Note, on Chrome it seems to be fine without
+     * this approach.
+    */
+  align-items: center;
+  background-clip: padding-box;
+  background-color: #455a64;
+  border: 0.5em solid rgba(136, 136, 136, 0);
+  border-radius: 3em;
+  bottom: 0;
+  color: #fff;
+  display: flex;
+  height: 0.5em;
+  justify-content: center;
+  left: -10px;
+  margin: auto;
+  position: absolute;
+  top: 0;
+  transition: border 120ms cubic-bezier(0.39, 0.58, 0.57, 1);
+  width: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-thumb.tinymce-mobile-thumb-active {
+  border: 0.5em solid rgba(136, 136, 136, 0.39);
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serializer-wrapper,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group > div {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serializer-wrapper {
+  flex-direction: column;
+  justify-content: center;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item {
+  align-items: center;
+  display: flex;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item:not(.tinymce-mobile-serialised-dialog) {
+  height: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-container {
+  display: flex;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input {
+  background: #ffffff;
+  border: none;
+  border-radius: 0;
+  color: #455a64;
+  flex-grow: 1;
+  font-size: 0.85em;
+  padding-bottom: 0.1em;
+  padding-left: 5px;
+  padding-top: 0.1em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input::-webkit-input-placeholder {
+  /* WebKit, Blink, Edge */
+  color: #888;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input::placeholder {
+  /* WebKit, Blink, Edge */
+  color: #888;
+}
+/* dropup */
+.tinymce-mobile-dropup {
+  background: white;
+  display: flex;
+  overflow: hidden;
+  width: 100%;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-shrinking {
+  transition: height 0.3s ease-out;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-growing {
+  transition: height 0.3s ease-in;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-closed {
+  flex-grow: 0;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-open:not(.tinymce-mobile-dropup-growing) {
+  flex-grow: 1;
+}
+/* TODO min-height for device size and orientation */
+.tinymce-mobile-ios-container .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
+  min-height: 200px;
+}
+@media only screen and (orientation: landscape) {
+  .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
+    min-height: 200px;
+  }
+}
+@media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : landscape) {
+  .tinymce-mobile-ios-container .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
+    min-height: 150px;
+  }
+}
+/* styles menu */
+.tinymce-mobile-styles-menu {
+  font-family: sans-serif;
+  outline: 4px solid black;
+  overflow: hidden;
+  position: relative;
+  width: 100%;
+}
+.tinymce-mobile-styles-menu [role="menu"] {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  position: absolute;
+  width: 100%;
+}
+.tinymce-mobile-styles-menu [role="menu"].transitioning {
+  transition: transform 0.5s ease-in-out;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-item {
+  border-bottom: 1px solid #ddd;
+  color: #455a64;
+  cursor: pointer;
+  display: flex;
+  padding: 1em 1em;
+  position: relative;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-collapser .tinymce-mobile-styles-collapse-icon::before {
+  color: #455a64;
+  content: "\e314";
+  font-family: 'tinymce-mobile', sans-serif;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-item.tinymce-mobile-styles-item-is-menu::after {
+  color: #455a64;
+  content: "\e315";
+  font-family: 'tinymce-mobile', sans-serif;
+  padding-left: 1em;
+  padding-right: 1em;
+  position: absolute;
+  right: 0;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-item.tinymce-mobile-format-matches::after {
+  font-family: 'tinymce-mobile', sans-serif;
+  padding-left: 1em;
+  padding-right: 1em;
+  position: absolute;
+  right: 0;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-separator,
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-collapser {
+  align-items: center;
+  background: #fff;
+  border-top: #455a64;
+  color: #455a64;
+  display: flex;
+  min-height: 2.5em;
+  padding-left: 1em;
+  padding-right: 1em;
+}
+.tinymce-mobile-styles-menu [data-transitioning-destination="before"][data-transitioning-state],
+.tinymce-mobile-styles-menu [data-transitioning-state="before"] {
+  transform: translate(-100%);
+}
+.tinymce-mobile-styles-menu [data-transitioning-destination="current"][data-transitioning-state],
+.tinymce-mobile-styles-menu [data-transitioning-state="current"] {
+  transform: translate(0%);
+}
+.tinymce-mobile-styles-menu [data-transitioning-destination="after"][data-transitioning-state],
+.tinymce-mobile-styles-menu [data-transitioning-state="after"] {
+  transform: translate(100%);
+}
+@font-face {
+  font-family: 'tinymce-mobile';
+  font-style: normal;
+  font-weight: normal;
+  src: url('fonts/tinymce-mobile.woff?8x92w3') format('woff');
+}
+@media (min-device-width: 700px) {
+  .tinymce-mobile-outer-container,
+  .tinymce-mobile-outer-container input {
+    font-size: 25px;
+  }
+}
+@media (max-device-width: 700px) {
+  .tinymce-mobile-outer-container,
+  .tinymce-mobile-outer-container input {
+    font-size: 18px;
+  }
+}
+.tinymce-mobile-icon {
+  font-family: 'tinymce-mobile', sans-serif;
+}
+.mixin-flex-and-centre {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+}
+.mixin-flex-bar {
+  align-items: center;
+  display: flex;
+  height: 100%;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-editor-socket iframe {
+  background-color: #fff;
+  width: 100%;
+}
+.tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
+  /* Note, on the iPod touch in landscape, this isn't visible when the navbar appears */
+  background-color: #207ab7;
+  border-radius: 50%;
+  bottom: 1em;
+  color: white;
+  font-size: 1em;
+  height: 2.1em;
+  position: fixed;
+  right: 2em;
+  width: 2.1em;
+  align-items: center;
+  display: flex;
+  justify-content: center;
+}
+@media only screen and (min-device-width:700px) {
+  .tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
+    font-size: 1.2em;
+  }
+}
+.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-editor-socket {
+  height: 300px;
+  overflow: hidden;
+}
+.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-editor-socket iframe {
+  height: 100%;
+}
+.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-toolstrip {
+  display: none;
+}
+/*
+  Note, that if you don't include this (::-webkit-file-upload-button), the toolbar width gets
+  increased and the whole body becomes scrollable. It's important!
+ */
+input[type="file"]::-webkit-file-upload-button {
+  display: none;
+}
+@media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : landscape) {
+  .tinymce-mobile-ios-container .tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
+    bottom: 50%;
+  }
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.mobile.min.css


+ 37 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.shadowdom.css

@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+body.tox-dialog__disable-scroll {
+  overflow: hidden;
+}
+.tox-fullscreen {
+  border: 0;
+  height: 100%;
+  left: 0;
+  margin: 0;
+  overflow: hidden;
+  -ms-scroll-chaining: none;
+      overscroll-behavior: none;
+  padding: 0;
+  position: fixed;
+  top: 0;
+  touch-action: pinch-zoom;
+  width: 100%;
+}
+.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle {
+  display: none;
+}
+.tox.tox-tinymce.tox-fullscreen {
+  background-color: transparent;
+  z-index: 1200;
+}
+.tox-shadowhost.tox-fullscreen {
+  z-index: 1200;
+}
+.tox-fullscreen .tox.tox-tinymce-aux,
+.tox-fullscreen ~ .tox.tox-tinymce-aux {
+  z-index: 1201;
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css


Разница между файлами не показана из-за своего большого размера
+ 732 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.css


Разница между файлами не показана из-за своего большого размера
+ 726 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.inline.css


Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.inline.min.css


Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.min.css


+ 29 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.mobile.css

@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection {
+  /* Note: this file is used inside the content, so isn't part of theming */
+  background-color: green;
+  display: inline-block;
+  opacity: 0.5;
+  position: absolute;
+}
+body {
+  -webkit-text-size-adjust: none;
+}
+body img {
+  /* this is related to the content margin */
+  max-width: 96vw;
+}
+body table img {
+  max-width: 95%;
+}
+body {
+  font-family: sans-serif;
+}
+table {
+  border-collapse: collapse;
+}

+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/content.mobile.min.css

@@ -0,0 +1,7 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse}

BIN
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff


Разница между файлами не показана из-за своего большого размера
+ 3029 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.css


Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.min.css


+ 673 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.mobile.css

@@ -0,0 +1,673 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+/* RESET all the things! */
+.tinymce-mobile-outer-container {
+  all: initial;
+  display: block;
+}
+.tinymce-mobile-outer-container * {
+  border: 0;
+  box-sizing: initial;
+  cursor: inherit;
+  float: none;
+  line-height: 1;
+  margin: 0;
+  outline: 0;
+  padding: 0;
+  -webkit-tap-highlight-color: transparent;
+  /* TBIO-3691, stop the gray flicker on touch. */
+  text-shadow: none;
+  white-space: nowrap;
+}
+.tinymce-mobile-icon-arrow-back::before {
+  content: "\e5cd";
+}
+.tinymce-mobile-icon-image::before {
+  content: "\e412";
+}
+.tinymce-mobile-icon-cancel-circle::before {
+  content: "\e5c9";
+}
+.tinymce-mobile-icon-full-dot::before {
+  content: "\e061";
+}
+.tinymce-mobile-icon-align-center::before {
+  content: "\e234";
+}
+.tinymce-mobile-icon-align-left::before {
+  content: "\e236";
+}
+.tinymce-mobile-icon-align-right::before {
+  content: "\e237";
+}
+.tinymce-mobile-icon-bold::before {
+  content: "\e238";
+}
+.tinymce-mobile-icon-italic::before {
+  content: "\e23f";
+}
+.tinymce-mobile-icon-unordered-list::before {
+  content: "\e241";
+}
+.tinymce-mobile-icon-ordered-list::before {
+  content: "\e242";
+}
+.tinymce-mobile-icon-font-size::before {
+  content: "\e245";
+}
+.tinymce-mobile-icon-underline::before {
+  content: "\e249";
+}
+.tinymce-mobile-icon-link::before {
+  content: "\e157";
+}
+.tinymce-mobile-icon-unlink::before {
+  content: "\eca2";
+}
+.tinymce-mobile-icon-color::before {
+  content: "\e891";
+}
+.tinymce-mobile-icon-previous::before {
+  content: "\e314";
+}
+.tinymce-mobile-icon-next::before {
+  content: "\e315";
+}
+.tinymce-mobile-icon-large-font::before,
+.tinymce-mobile-icon-style-formats::before {
+  content: "\e264";
+}
+.tinymce-mobile-icon-undo::before {
+  content: "\e166";
+}
+.tinymce-mobile-icon-redo::before {
+  content: "\e15a";
+}
+.tinymce-mobile-icon-removeformat::before {
+  content: "\e239";
+}
+.tinymce-mobile-icon-small-font::before {
+  content: "\e906";
+}
+.tinymce-mobile-icon-readonly-back::before,
+.tinymce-mobile-format-matches::after {
+  content: "\e5ca";
+}
+.tinymce-mobile-icon-small-heading::before {
+  content: "small";
+}
+.tinymce-mobile-icon-large-heading::before {
+  content: "large";
+}
+.tinymce-mobile-icon-small-heading::before,
+.tinymce-mobile-icon-large-heading::before {
+  font-family: sans-serif;
+  font-size: 80%;
+}
+.tinymce-mobile-mask-edit-icon::before {
+  content: "\e254";
+}
+.tinymce-mobile-icon-back::before {
+  content: "\e5c4";
+}
+.tinymce-mobile-icon-heading::before {
+  /* TODO: Translate */
+  content: "Headings";
+  font-family: sans-serif;
+  font-size: 80%;
+  font-weight: bold;
+}
+.tinymce-mobile-icon-h1::before {
+  content: "H1";
+  font-weight: bold;
+}
+.tinymce-mobile-icon-h2::before {
+  content: "H2";
+  font-weight: bold;
+}
+.tinymce-mobile-icon-h3::before {
+  content: "H3";
+  font-weight: bold;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  background: rgba(51, 51, 51, 0.5);
+  height: 100%;
+  position: absolute;
+  top: 0;
+  width: 100%;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container {
+  align-items: center;
+  border-radius: 50%;
+  display: flex;
+  flex-direction: column;
+  font-family: sans-serif;
+  font-size: 1em;
+  justify-content: space-between;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .mixin-menu-item {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  border-radius: 50%;
+  height: 2.1em;
+  width: 2.1em;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  flex-direction: column;
+  font-size: 1em;
+}
+@media only screen and (min-device-width:700px) {
+  .tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section {
+    font-size: 1.2em;
+  }
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section .tinymce-mobile-mask-tap-icon {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+  border-radius: 50%;
+  height: 2.1em;
+  width: 2.1em;
+  background-color: white;
+  color: #207ab7;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section .tinymce-mobile-mask-tap-icon::before {
+  content: "\e900";
+  font-family: 'tinymce-mobile', sans-serif;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section:not(.tinymce-mobile-mask-tap-icon-selected) .tinymce-mobile-mask-tap-icon {
+  z-index: 2;
+}
+.tinymce-mobile-android-container.tinymce-mobile-android-maximized {
+  background: #ffffff;
+  border: none;
+  bottom: 0;
+  display: flex;
+  flex-direction: column;
+  left: 0;
+  position: fixed;
+  right: 0;
+  top: 0;
+}
+.tinymce-mobile-android-container:not(.tinymce-mobile-android-maximized) {
+  position: relative;
+}
+.tinymce-mobile-android-container .tinymce-mobile-editor-socket {
+  display: flex;
+  flex-grow: 1;
+}
+.tinymce-mobile-android-container .tinymce-mobile-editor-socket iframe {
+  display: flex !important;
+  flex-grow: 1;
+  height: auto !important;
+}
+.tinymce-mobile-android-scroll-reload {
+  overflow: hidden;
+}
+:not(.tinymce-mobile-readonly-mode) > .tinymce-mobile-android-selection-context-toolbar {
+  margin-top: 23px;
+}
+.tinymce-mobile-toolstrip {
+  background: #fff;
+  display: flex;
+  flex: 0 0 auto;
+  z-index: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar {
+  align-items: center;
+  background-color: #fff;
+  border-bottom: 1px solid #cccccc;
+  display: flex;
+  flex: 1;
+  height: 2.5em;
+  width: 100%;
+  /* Make it no larger than the toolstrip, so that it needs to scroll */
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex-shrink: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group > div {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group.tinymce-mobile-exit-container {
+  background: #f44336;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group.tinymce-mobile-toolbar-scrollable-group {
+  flex-grow: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item {
+  padding-left: 0.5em;
+  padding-right: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item.tinymce-mobile-toolbar-button {
+  align-items: center;
+  display: flex;
+  height: 80%;
+  margin-left: 2px;
+  margin-right: 2px;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item.tinymce-mobile-toolbar-button.tinymce-mobile-toolbar-button-selected {
+  background: #c8cbcf;
+  color: #cccccc;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group:first-of-type,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group:last-of-type {
+  background: #207ab7;
+  color: #eceff1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar {
+  /* Note, this file is imported inside .tinymce-mobile-context-toolbar, so that prefix is on everything here. */
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex: 1;
+  padding-bottom: 0.4em;
+  padding-top: 0.4em;
+  /* Make any buttons appearing on the left and right display in the centre (e.g. color edges) */
+  /* For widgets like the colour picker, use the whole height */
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog {
+  display: flex;
+  min-height: 1.5em;
+  overflow: hidden;
+  padding-left: 0;
+  padding-right: 0;
+  position: relative;
+  width: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain {
+  display: flex;
+  height: 100%;
+  transition: left cubic-bezier(0.4, 0, 1, 1) 0.15s;
+  width: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen {
+  display: flex;
+  flex: 0 0 auto;
+  justify-content: space-between;
+  width: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen input {
+  font-family: Sans-serif;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container {
+  display: flex;
+  flex-grow: 1;
+  position: relative;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container .tinymce-mobile-input-container-x {
+  -ms-grid-row-align: center;
+      align-self: center;
+  background: inherit;
+  border: none;
+  border-radius: 50%;
+  color: #888;
+  font-size: 0.6em;
+  font-weight: bold;
+  height: 100%;
+  padding-right: 2px;
+  position: absolute;
+  right: 0;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container.tinymce-mobile-input-container-empty .tinymce-mobile-input-container-x {
+  display: none;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next {
+  align-items: center;
+  display: flex;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next::before {
+  align-items: center;
+  display: flex;
+  font-weight: bold;
+  height: 100%;
+  padding-left: 0.5em;
+  padding-right: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous.tinymce-mobile-toolbar-navigation-disabled::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next.tinymce-mobile-toolbar-navigation-disabled::before {
+  visibility: hidden;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-item {
+  color: #cccccc;
+  font-size: 10px;
+  line-height: 10px;
+  margin: 0 2px;
+  padding-top: 3px;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-item.tinymce-mobile-dot-active {
+  color: #c8cbcf;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-large-font::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-large-heading::before {
+  margin-left: 0.5em;
+  margin-right: 0.9em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-small-font::before,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-small-heading::before {
+  margin-left: 0.9em;
+  margin-right: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider {
+  display: flex;
+  flex: 1;
+  margin-left: 0;
+  margin-right: 0;
+  padding: 0.28em 0;
+  position: relative;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-size-container {
+  align-items: center;
+  display: flex;
+  flex-grow: 1;
+  height: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-size-container .tinymce-mobile-slider-size-line {
+  background: #cccccc;
+  display: flex;
+  flex: 1;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container {
+  padding-left: 2em;
+  padding-right: 2em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-slider-gradient-container {
+  align-items: center;
+  display: flex;
+  flex-grow: 1;
+  height: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-slider-gradient-container .tinymce-mobile-slider-gradient {
+  background: linear-gradient(to right, hsl(0, 100%, 50%) 0%, hsl(60, 100%, 50%) 17%, hsl(120, 100%, 50%) 33%, hsl(180, 100%, 50%) 50%, hsl(240, 100%, 50%) 67%, hsl(300, 100%, 50%) 83%, hsl(0, 100%, 50%) 100%);
+  display: flex;
+  flex: 1;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-hue-slider-black {
+  /* Not part of theming */
+  background: black;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+  width: 1.2em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-hue-slider-white {
+  /* Not part of theming */
+  background: white;
+  height: 0.2em;
+  margin-bottom: 0.3em;
+  margin-top: 0.3em;
+  width: 1.2em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-thumb {
+  /* vertically centering trick (margin: auto, top: 0, bottom: 0). On iOS and Safari, if you leave
+     * out these values, then it shows the thumb at the top of the spectrum. This is probably because it is
+     * absolutely positioned with only a left value, and not a top. Note, on Chrome it seems to be fine without
+     * this approach.
+    */
+  align-items: center;
+  background-clip: padding-box;
+  background-color: #455a64;
+  border: 0.5em solid rgba(136, 136, 136, 0);
+  border-radius: 3em;
+  bottom: 0;
+  color: #fff;
+  display: flex;
+  height: 0.5em;
+  justify-content: center;
+  left: -10px;
+  margin: auto;
+  position: absolute;
+  top: 0;
+  transition: border 120ms cubic-bezier(0.39, 0.58, 0.57, 1);
+  width: 0.5em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-thumb.tinymce-mobile-thumb-active {
+  border: 0.5em solid rgba(136, 136, 136, 0.39);
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serializer-wrapper,
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group > div {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  flex: 1;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serializer-wrapper {
+  flex-direction: column;
+  justify-content: center;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item {
+  align-items: center;
+  display: flex;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item:not(.tinymce-mobile-serialised-dialog) {
+  height: 100%;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-container {
+  display: flex;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input {
+  background: #ffffff;
+  border: none;
+  border-radius: 0;
+  color: #455a64;
+  flex-grow: 1;
+  font-size: 0.85em;
+  padding-bottom: 0.1em;
+  padding-left: 5px;
+  padding-top: 0.1em;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input::-webkit-input-placeholder {
+  /* WebKit, Blink, Edge */
+  color: #888;
+}
+.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input::placeholder {
+  /* WebKit, Blink, Edge */
+  color: #888;
+}
+/* dropup */
+.tinymce-mobile-dropup {
+  background: white;
+  display: flex;
+  overflow: hidden;
+  width: 100%;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-shrinking {
+  transition: height 0.3s ease-out;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-growing {
+  transition: height 0.3s ease-in;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-closed {
+  flex-grow: 0;
+}
+.tinymce-mobile-dropup.tinymce-mobile-dropup-open:not(.tinymce-mobile-dropup-growing) {
+  flex-grow: 1;
+}
+/* TODO min-height for device size and orientation */
+.tinymce-mobile-ios-container .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
+  min-height: 200px;
+}
+@media only screen and (orientation: landscape) {
+  .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
+    min-height: 200px;
+  }
+}
+@media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : landscape) {
+  .tinymce-mobile-ios-container .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
+    min-height: 150px;
+  }
+}
+/* styles menu */
+.tinymce-mobile-styles-menu {
+  font-family: sans-serif;
+  outline: 4px solid black;
+  overflow: hidden;
+  position: relative;
+  width: 100%;
+}
+.tinymce-mobile-styles-menu [role="menu"] {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  position: absolute;
+  width: 100%;
+}
+.tinymce-mobile-styles-menu [role="menu"].transitioning {
+  transition: transform 0.5s ease-in-out;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-item {
+  border-bottom: 1px solid #ddd;
+  color: #455a64;
+  cursor: pointer;
+  display: flex;
+  padding: 1em 1em;
+  position: relative;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-collapser .tinymce-mobile-styles-collapse-icon::before {
+  color: #455a64;
+  content: "\e314";
+  font-family: 'tinymce-mobile', sans-serif;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-item.tinymce-mobile-styles-item-is-menu::after {
+  color: #455a64;
+  content: "\e315";
+  font-family: 'tinymce-mobile', sans-serif;
+  padding-left: 1em;
+  padding-right: 1em;
+  position: absolute;
+  right: 0;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-item.tinymce-mobile-format-matches::after {
+  font-family: 'tinymce-mobile', sans-serif;
+  padding-left: 1em;
+  padding-right: 1em;
+  position: absolute;
+  right: 0;
+}
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-separator,
+.tinymce-mobile-styles-menu .tinymce-mobile-styles-collapser {
+  align-items: center;
+  background: #fff;
+  border-top: #455a64;
+  color: #455a64;
+  display: flex;
+  min-height: 2.5em;
+  padding-left: 1em;
+  padding-right: 1em;
+}
+.tinymce-mobile-styles-menu [data-transitioning-destination="before"][data-transitioning-state],
+.tinymce-mobile-styles-menu [data-transitioning-state="before"] {
+  transform: translate(-100%);
+}
+.tinymce-mobile-styles-menu [data-transitioning-destination="current"][data-transitioning-state],
+.tinymce-mobile-styles-menu [data-transitioning-state="current"] {
+  transform: translate(0%);
+}
+.tinymce-mobile-styles-menu [data-transitioning-destination="after"][data-transitioning-state],
+.tinymce-mobile-styles-menu [data-transitioning-state="after"] {
+  transform: translate(100%);
+}
+@font-face {
+  font-family: 'tinymce-mobile';
+  font-style: normal;
+  font-weight: normal;
+  src: url('fonts/tinymce-mobile.woff?8x92w3') format('woff');
+}
+@media (min-device-width: 700px) {
+  .tinymce-mobile-outer-container,
+  .tinymce-mobile-outer-container input {
+    font-size: 25px;
+  }
+}
+@media (max-device-width: 700px) {
+  .tinymce-mobile-outer-container,
+  .tinymce-mobile-outer-container input {
+    font-size: 18px;
+  }
+}
+.tinymce-mobile-icon {
+  font-family: 'tinymce-mobile', sans-serif;
+}
+.mixin-flex-and-centre {
+  align-items: center;
+  display: flex;
+  justify-content: center;
+}
+.mixin-flex-bar {
+  align-items: center;
+  display: flex;
+  height: 100%;
+}
+.tinymce-mobile-outer-container .tinymce-mobile-editor-socket iframe {
+  background-color: #fff;
+  width: 100%;
+}
+.tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
+  /* Note, on the iPod touch in landscape, this isn't visible when the navbar appears */
+  background-color: #207ab7;
+  border-radius: 50%;
+  bottom: 1em;
+  color: white;
+  font-size: 1em;
+  height: 2.1em;
+  position: fixed;
+  right: 2em;
+  width: 2.1em;
+  align-items: center;
+  display: flex;
+  justify-content: center;
+}
+@media only screen and (min-device-width:700px) {
+  .tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
+    font-size: 1.2em;
+  }
+}
+.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-editor-socket {
+  height: 300px;
+  overflow: hidden;
+}
+.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-editor-socket iframe {
+  height: 100%;
+}
+.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-toolstrip {
+  display: none;
+}
+/*
+  Note, that if you don't include this (::-webkit-file-upload-button), the toolbar width gets
+  increased and the whole body becomes scrollable. It's important!
+ */
+input[type="file"]::-webkit-file-upload-button {
+  display: none;
+}
+@media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : landscape) {
+  .tinymce-mobile-ios-container .tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
+    bottom: 50%;
+  }
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.mobile.min.css


+ 37 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.shadowdom.css

@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) Tiny Technologies, Inc. All rights reserved.
+ * Licensed under the LGPL or a commercial license.
+ * For LGPL see License.txt in the project root for license information.
+ * For commercial licenses see https://www.tiny.cloud/
+ */
+body.tox-dialog__disable-scroll {
+  overflow: hidden;
+}
+.tox-fullscreen {
+  border: 0;
+  height: 100%;
+  left: 0;
+  margin: 0;
+  overflow: hidden;
+  -ms-scroll-chaining: none;
+      overscroll-behavior: none;
+  padding: 0;
+  position: fixed;
+  top: 0;
+  touch-action: pinch-zoom;
+  width: 100%;
+}
+.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle {
+  display: none;
+}
+.tox.tox-tinymce.tox-fullscreen {
+  background-color: transparent;
+  z-index: 1200;
+}
+.tox-shadowhost.tox-fullscreen {
+  z-index: 1200;
+}
+.tox-fullscreen .tox.tox-tinymce-aux,
+.tox-fullscreen ~ .tox.tox-tinymce-aux {
+  z-index: 1201;
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/skins/ui/oxide/skin.shadowdom.min.css


+ 419 - 0
fhKeeper/formulahousekeeper/timesheet/static/tinymce/zh_CN.js

@@ -0,0 +1,419 @@
+tinymce.addI18n('zh_CN',{
+"Redo": "\u91cd\u505a",
+"Undo": "\u64a4\u9500",
+"Cut": "\u526a\u5207",
+"Copy": "\u590d\u5236",
+"Paste": "\u7c98\u8d34",
+"Select all": "\u5168\u9009",
+"New document": "\u65b0\u6587\u4ef6",
+"Ok": "\u786e\u5b9a",
+"Cancel": "\u53d6\u6d88",
+"Visual aids": "\u7f51\u683c\u7ebf",
+"Bold": "\u7c97\u4f53",
+"Italic": "\u659c\u4f53",
+"Underline": "\u4e0b\u5212\u7ebf",
+"Strikethrough": "\u5220\u9664\u7ebf",
+"Superscript": "\u4e0a\u6807",
+"Subscript": "\u4e0b\u6807",
+"Clear formatting": "\u6e05\u9664\u683c\u5f0f",
+"Align left": "\u5de6\u8fb9\u5bf9\u9f50",
+"Align center": "\u4e2d\u95f4\u5bf9\u9f50",
+"Align right": "\u53f3\u8fb9\u5bf9\u9f50",
+"Justify": "\u4e24\u7aef\u5bf9\u9f50",
+"Bullet list": "\u9879\u76ee\u7b26\u53f7",
+"Numbered list": "\u7f16\u53f7\u5217\u8868",
+"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb",
+"Increase indent": "\u589e\u52a0\u7f29\u8fdb",
+"Close": "\u5173\u95ed",
+"Formats": "\u683c\u5f0f",
+"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002",
+"Headers": "\u6807\u9898",
+"Header 1": "\u6807\u98981",
+"Header 2": "\u6807\u98982",
+"Header 3": "\u6807\u98983",
+"Header 4": "\u6807\u98984",
+"Header 5": "\u6807\u98985",
+"Header 6": "\u6807\u98986",
+"Headings": "\u6807\u9898",
+"Heading 1": "\u6807\u98981",
+"Heading 2": "\u6807\u98982",
+"Heading 3": "\u6807\u98983",
+"Heading 4": "\u6807\u98984",
+"Heading 5": "\u6807\u98985",
+"Heading 6": "\u6807\u98986",
+"Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684",
+"Div": "Div",
+"Pre": "Pre",
+"Code": "\u4ee3\u7801",
+"Paragraph": "\u6bb5\u843d",
+"Blockquote": "\u5f15\u6587\u533a\u5757",
+"Inline": "\u6587\u672c",
+"Blocks": "\u57fa\u5757",
+"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",
+"Fonts": "\u5b57\u4f53",
+"Font Sizes": "\u5b57\u53f7",
+"Class": "\u7c7b\u578b",
+"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf",
+"OR": "\u6216",
+"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",
+"Upload": "\u4e0a\u4f20",
+"Block": "\u5757",
+"Align": "\u5bf9\u9f50",
+"Default": "\u9ed8\u8ba4",
+"Circle": "\u7a7a\u5fc3\u5706",
+"Disc": "\u5b9e\u5fc3\u5706",
+"Square": "\u65b9\u5757",
+"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd",
+"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd",
+"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd",
+"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd",
+"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd",
+"Anchor...": "\u951a\u70b9...",
+"Name": "\u540d\u79f0",
+"Id": "\u6807\u8bc6\u7b26",
+"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002",
+"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f",
+"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f",
+"Special character...": "\u7279\u6b8a\u5b57\u7b26...",
+"Source code": "\u6e90\u4ee3\u7801",
+"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",
+"Language": "\u8bed\u8a00",
+"Code sample...": "\u793a\u4f8b\u4ee3\u7801...",
+"Color Picker": "\u9009\u8272\u5668",
+"R": "R",
+"G": "G",
+"B": "B",
+"Left to right": "\u4ece\u5de6\u5230\u53f3",
+"Right to left": "\u4ece\u53f3\u5230\u5de6",
+"Emoticons...": "\u8868\u60c5\u7b26\u53f7...",
+"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027",
+"Title": "\u6807\u9898",
+"Keywords": "\u5173\u952e\u8bcd",
+"Description": "\u63cf\u8ff0",
+"Robots": "\u673a\u5668\u4eba",
+"Author": "\u4f5c\u8005",
+"Encoding": "\u7f16\u7801",
+"Fullscreen": "\u5168\u5c4f",
+"Action": "\u64cd\u4f5c",
+"Shortcut": "\u5feb\u6377\u952e",
+"Help": "\u5e2e\u52a9",
+"Address": "\u5730\u5740",
+"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f",
+"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f",
+"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84",
+"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355",
+"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
+"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
+"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
+"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):",
+"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a",
+"Learn more...": "\u4e86\u89e3\u66f4\u591a...",
+"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}",
+"Plugins": "\u63d2\u4ef6",
+"Handy Shortcuts": "\u5feb\u6377\u952e",
+"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf",
+"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247",
+"Image description": "\u56fe\u7247\u63cf\u8ff0",
+"Source": "\u5730\u5740",
+"Dimensions": "\u5927\u5c0f",
+"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4",
+"General": "\u666e\u901a",
+"Advanced": "\u9ad8\u7ea7",
+"Style": "\u6837\u5f0f",
+"Vertical space": "\u5782\u76f4\u8fb9\u8ddd",
+"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd",
+"Border": "\u8fb9\u6846",
+"Insert image": "\u63d2\u5165\u56fe\u7247",
+"Image...": "\u56fe\u7247...",
+"Image list": "\u56fe\u7247\u5217\u8868",
+"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c",
+"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c",
+"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c",
+"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c",
+"Edit image": "\u7f16\u8f91\u56fe\u7247",
+"Image options": "\u56fe\u7247\u9009\u9879",
+"Zoom in": "\u653e\u5927",
+"Zoom out": "\u7f29\u5c0f",
+"Crop": "\u88c1\u526a",
+"Resize": "\u8c03\u6574\u5927\u5c0f",
+"Orientation": "\u65b9\u5411",
+"Brightness": "\u4eae\u5ea6",
+"Sharpen": "\u9510\u5316",
+"Contrast": "\u5bf9\u6bd4\u5ea6",
+"Color levels": "\u989c\u8272\u5c42\u6b21",
+"Gamma": "\u4f3d\u9a6c\u503c",
+"Invert": "\u53cd\u8f6c",
+"Apply": "\u5e94\u7528",
+"Back": "\u540e\u9000",
+"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4",
+"Date\/time": "\u65e5\u671f\/\u65f6\u95f4",
+"Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
+"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
+"Text to display": "\u663e\u793a\u6587\u5b57",
+"Url": "\u5730\u5740",
+"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...",
+"Current window": "\u5f53\u524d\u7a97\u53e3",
+"None": "\u65e0",
+"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00",
+"Remove link": "\u5220\u9664\u94fe\u63a5",
+"Anchors": "\u951a\u70b9",
+"Link...": "\u94fe\u63a5...",
+"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5",
+"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f",
+"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f",
+"Link list": "\u94fe\u63a5\u5217\u8868",
+"Insert video": "\u63d2\u5165\u89c6\u9891",
+"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891",
+"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53",
+"Alternative source": "\u955c\u50cf",
+"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740",
+"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)",
+"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",
+"Embed": "\u5185\u5d4c",
+"Media...": "\u591a\u5a92\u4f53...",
+"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c",
+"Page break": "\u5206\u9875\u7b26",
+"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c",
+"Preview": "\u9884\u89c8",
+"Print...": "\u6253\u5370...",
+"Save": "\u4fdd\u5b58",
+"Find": "\u67e5\u627e",
+"Replace with": "\u66ff\u6362\u4e3a",
+"Replace": "\u66ff\u6362",
+"Replace all": "\u5168\u90e8\u66ff\u6362",
+"Previous": "\u4e0a\u4e00\u4e2a",
+"Next": "\u4e0b\u4e00\u4e2a",
+"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...",
+"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.",
+"Match case": "\u533a\u5206\u5927\u5c0f\u5199",
+"Find whole words only": "\u5168\u5b57\u5339\u914d",
+"Spell check": "\u62fc\u5199\u68c0\u67e5",
+"Ignore": "\u5ffd\u7565",
+"Ignore all": "\u5168\u90e8\u5ffd\u7565",
+"Finish": "\u5b8c\u6210",
+"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178",
+"Insert table": "\u63d2\u5165\u8868\u683c",
+"Table properties": "\u8868\u683c\u5c5e\u6027",
+"Delete table": "\u5220\u9664\u8868\u683c",
+"Cell": "\u5355\u5143\u683c",
+"Row": "\u884c",
+"Column": "\u5217",
+"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027",
+"Merge cells": "\u5408\u5e76\u5355\u5143\u683c",
+"Split cell": "\u62c6\u5206\u5355\u5143\u683c",
+"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165",
+"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165",
+"Delete row": "\u5220\u9664\u884c",
+"Row properties": "\u884c\u5c5e\u6027",
+"Cut row": "\u526a\u5207\u884c",
+"Copy row": "\u590d\u5236\u884c",
+"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9",
+"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9",
+"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165",
+"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165",
+"Delete column": "\u5220\u9664\u5217",
+"Cols": "\u5217",
+"Rows": "\u884c",
+"Width": "\u5bbd",
+"Height": "\u9ad8",
+"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd",
+"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd",
+"Show caption": "\u663e\u793a\u6807\u9898",
+"Left": "\u5de6\u5bf9\u9f50",
+"Center": "\u5c45\u4e2d",
+"Right": "\u53f3\u5bf9\u9f50",
+"Cell type": "\u5355\u5143\u683c\u7c7b\u578b",
+"Scope": "\u8303\u56f4",
+"Alignment": "\u5bf9\u9f50\u65b9\u5f0f",
+"H Align": "\u6c34\u5e73\u5bf9\u9f50",
+"V Align": "\u5782\u76f4\u5bf9\u9f50",
+"Top": "\u9876\u90e8\u5bf9\u9f50",
+"Middle": "\u5782\u76f4\u5c45\u4e2d",
+"Bottom": "\u5e95\u90e8\u5bf9\u9f50",
+"Header cell": "\u8868\u5934\u5355\u5143\u683c",
+"Row group": "\u884c\u7ec4",
+"Column group": "\u5217\u7ec4",
+"Row type": "\u884c\u7c7b\u578b",
+"Header": "\u8868\u5934",
+"Body": "\u8868\u4f53",
+"Footer": "\u8868\u5c3e",
+"Border color": "\u8fb9\u6846\u989c\u8272",
+"Insert template...": "\u63d2\u5165\u6a21\u677f...",
+"Templates": "\u6a21\u677f",
+"Template": "\u6a21\u677f",
+"Text color": "\u6587\u5b57\u989c\u8272",
+"Background color": "\u80cc\u666f\u8272",
+"Custom...": "\u81ea\u5b9a\u4e49...",
+"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272",
+"No color": "\u65e0",
+"Remove color": "\u79fb\u9664\u989c\u8272",
+"Table of Contents": "\u5185\u5bb9\u5217\u8868",
+"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846",
+"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26",
+"Word count": "\u5b57\u6570",
+"Count": "\u8ba1\u6570",
+"Document": "\u6587\u6863",
+"Selection": "\u9009\u62e9",
+"Words": "\u5355\u8bcd",
+"Words: {0}": "\u5b57\u6570\uff1a{0}",
+"{0} words": "{0} \u5b57",
+"File": "\u6587\u4ef6",
+"Edit": "\u7f16\u8f91",
+"Insert": "\u63d2\u5165",
+"View": "\u89c6\u56fe",
+"Format": "\u683c\u5f0f",
+"Table": "\u8868\u683c",
+"Tools": "\u5de5\u5177",
+"Powered by {0}": "\u7531{0}\u9a71\u52a8",
+"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9",
+"Image title": "\u56fe\u7247\u6807\u9898",
+"Border width": "\u8fb9\u6846\u5bbd\u5ea6",
+"Border style": "\u8fb9\u6846\u6837\u5f0f",
+"Error": "\u9519\u8bef",
+"Warn": "\u8b66\u544a",
+"Valid": "\u6709\u6548",
+"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846",
+"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002",
+"System Font": "\u7cfb\u7edf\u5b57\u4f53",
+"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}",
+"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}",
+"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}",
+"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}",
+"example": "\u793a\u4f8b",
+"Search": "\u641c\u7d22",
+"All": "\u5168\u90e8",
+"Currency": "\u8d27\u5e01",
+"Text": "\u6587\u5b57",
+"Quotations": "\u5f15\u7528",
+"Mathematical": "\u6570\u5b66",
+"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145",
+"Symbols": "\u7b26\u53f7",
+"Arrows": "\u7bad\u5934",
+"User Defined": "\u81ea\u5b9a\u4e49",
+"dollar sign": "\u7f8e\u5143\u7b26\u53f7",
+"currency sign": "\u8d27\u5e01\u7b26\u53f7",
+"euro-currency sign": "\u6b27\u5143\u7b26\u53f7",
+"colon sign": "\u5192\u53f7",
+"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7",
+"french franc sign": "\u6cd5\u90ce\u7b26\u53f7",
+"lira sign": "\u91cc\u62c9\u7b26\u53f7",
+"mill sign": "\u5bc6\u5c14\u7b26\u53f7",
+"naira sign": "\u5948\u62c9\u7b26\u53f7",
+"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7",
+"rupee sign": "\u5362\u6bd4\u7b26\u53f7",
+"won sign": "\u97e9\u5143\u7b26\u53f7",
+"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7",
+"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7",
+"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7",
+"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7",
+"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7",
+"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7",
+"peso sign": "\u6bd4\u7d22\u7b26\u53f7",
+"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7",
+"austral sign": "\u6fb3\u5143\u7b26\u53f7",
+"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7",
+"cedi sign": "\u585e\u5730\u7b26\u53f7",
+"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7",
+"spesmilo sign": "spesmilo\u7b26\u53f7",
+"tenge sign": "\u575a\u6208\u7b26\u53f7",
+"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4",
+"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9",
+"nordic mark sign": "\u5317\u6b27\u9a6c\u514b",
+"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7",
+"ruble sign": "\u5362\u5e03\u7b26\u53f7",
+"yen character": "\u65e5\u5143\u5b57\u6837",
+"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837",
+"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09",
+"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09",
+"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...",
+"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7",
+"People": "\u4eba\u7c7b",
+"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136",
+"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1",
+"Activity": "\u6d3b\u52a8",
+"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9",
+"Objects": "\u7269\u4ef6",
+"Flags": "\u65d7\u5e1c",
+"Characters": "\u5b57\u7b26",
+"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)",
+"{0} characters": "{0} \u4e2a\u5b57\u7b26",
+"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002",
+"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002",
+"Update": "\u66f4\u65b0",
+"Color swatch": "\u989c\u8272\u6837\u672c",
+"Turquoise": "\u9752\u7eff\u8272",
+"Green": "\u7eff\u8272",
+"Blue": "\u84dd\u8272",
+"Purple": "\u7d2b\u8272",
+"Navy Blue": "\u6d77\u519b\u84dd",
+"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272",
+"Dark Green": "\u6df1\u7eff\u8272",
+"Medium Blue": "\u4e2d\u84dd\u8272",
+"Medium Purple": "\u4e2d\u7d2b\u8272",
+"Midnight Blue": "\u6df1\u84dd\u8272",
+"Yellow": "\u9ec4\u8272",
+"Orange": "\u6a59\u8272",
+"Red": "\u7ea2\u8272",
+"Light Gray": "\u6d45\u7070\u8272",
+"Gray": "\u7070\u8272",
+"Dark Yellow": "\u6697\u9ec4\u8272",
+"Dark Orange": "\u6df1\u6a59\u8272",
+"Dark Red": "\u6df1\u7ea2\u8272",
+"Medium Gray": "\u4e2d\u7070\u8272",
+"Dark Gray": "\u6df1\u7070\u8272",
+"Light Green": "\u6d45\u7eff\u8272",
+"Light Yellow": "\u6d45\u9ec4\u8272",
+"Light Red": "\u6d45\u7ea2\u8272",
+"Light Purple": "\u6d45\u7d2b\u8272",
+"Light Blue": "\u6d45\u84dd\u8272",
+"Dark Purple": "\u6df1\u7d2b\u8272",
+"Dark Blue": "\u6df1\u84dd\u8272",
+"Black": "\u9ed1\u8272",
+"White": "\u767d\u8272",
+"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f",
+"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846",
+"history": "\u5386\u53f2",
+"styles": "\u6837\u5f0f",
+"formatting": "\u683c\u5f0f\u5316",
+"alignment": "\u5bf9\u9f50",
+"indentation": "\u7f29\u8fdb",
+"permanent pen": "\u8bb0\u53f7\u7b14",
+"comments": "\u5907\u6ce8",
+"Format Painter": "\u683c\u5f0f\u5237",
+"Insert\/edit iframe": "\u63d2\u5165\/\u7f16\u8f91\u6846\u67b6",
+"Capitalization": "\u5927\u5199",
+"lowercase": "\u5c0f\u5199",
+"UPPERCASE": "\u5927\u5199",
+"Title Case": "\u9996\u5b57\u6bcd\u5927\u5199",
+"Permanent Pen Properties": "\u6c38\u4e45\u7b14\u5c5e\u6027",
+"Permanent pen properties...": "\u6c38\u4e45\u7b14\u5c5e\u6027...",
+"Font": "\u5b57\u4f53",
+"Size": "\u5b57\u53f7",
+"More...": "\u66f4\u591a...",
+"Spellcheck Language": "\u62fc\u5199\u68c0\u67e5\u8bed\u8a00",
+"Select...": "\u9009\u62e9...",
+"Preferences": "\u9996\u9009\u9879",
+"Yes": "\u662f",
+"No": "\u5426",
+"Keyboard Navigation": "\u952e\u76d8\u6307\u5f15",
+"Version": "\u7248\u672c",
+"Anchor": "\u951a\u70b9",
+"Special character": "\u7279\u6b8a\u7b26\u53f7",
+"Code sample": "\u4ee3\u7801\u793a\u4f8b",
+"Color": "\u989c\u8272",
+"Emoticons": "\u8868\u60c5",
+"Document properties": "\u6587\u6863\u5c5e\u6027",
+"Image": "\u56fe\u7247",
+"Insert link": "\u63d2\u5165\u94fe\u63a5",
+"Target": "\u6253\u5f00\u65b9\u5f0f",
+"Link": "\u94fe\u63a5",
+"Poster": "\u5c01\u9762",
+"Media": "\u5a92\u4f53",
+"Print": "\u6253\u5370",
+"Prev": "\u4e0a\u4e00\u4e2a",
+"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362",
+"Whole words": "\u5168\u5b57\u5339\u914d",
+"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
+"Caption": "\u6807\u9898",
+"Insert template": "\u63d2\u5165\u6a21\u677f"
+});

BIN
fhKeeper/formulahousekeeper/timesheet/static/upload/0b7c576ac90b4503bba8c2b36c15517a.pdf


BIN
fhKeeper/formulahousekeeper/timesheet/static/upload/222.pdf