Kaynağa Gözat

适配移动端

kuaifan 5 yıl önce
ebeveyn
işleme
5ea7f3b2bf
45 değiştirilmiş dosya ile 717 ekleme ve 174 silme
  1. 1 0
      .env.docker
  2. 4 1
      app/Http/Controllers/Api/DocsController.php
  3. 34 1
      app/Http/Controllers/Api/ProjectController.php
  4. 2 2
      app/Http/Controllers/Api/UsersController.php
  5. 9 4
      bin/wookteam
  6. 3 3
      config/laravels.php
  7. 2 0
      database/seeds/UsersTableSeeder.php
  8. 1 0
      docker-compose.yml
  9. 2 0
      docker/site.conf
  10. 2 2
      install/DOCKER.md
  11. 2 2
      install/en/DOCKER.md
  12. 1 1
      package.json
  13. 9 0
      resources/assets/js/common.js
  14. 21 0
      resources/assets/js/main/components/ImgUpload.vue
  15. 29 5
      resources/assets/js/main/components/MDEditor/index.vue
  16. 24 16
      resources/assets/js/main/components/TEditor.vue
  17. 78 25
      resources/assets/js/main/components/UserInput.vue
  18. 44 1
      resources/assets/js/main/components/WHeader.vue
  19. 1 1
      resources/assets/js/main/components/docs/users.vue
  20. 1 1
      resources/assets/js/main/components/project/archived.vue
  21. 2 2
      resources/assets/js/main/components/project/gantt/index.vue
  22. 1 1
      resources/assets/js/main/components/project/header/archived.vue
  23. 1 1
      resources/assets/js/main/components/project/header/create.vue
  24. 1 1
      resources/assets/js/main/components/project/my/favor.vue
  25. 1 1
      resources/assets/js/main/components/project/my/join.vue
  26. 1 1
      resources/assets/js/main/components/project/my/manage.vue
  27. 1 1
      resources/assets/js/main/components/project/statistics.vue
  28. 35 8
      resources/assets/js/main/components/project/task/detail/DescEditor.vue
  29. 190 70
      resources/assets/js/main/components/project/task/detail/detail.vue
  30. 1 1
      resources/assets/js/main/components/project/task/files.vue
  31. 1 1
      resources/assets/js/main/components/project/task/lists.vue
  32. 1 1
      resources/assets/js/main/components/project/todo/attention.vue
  33. 1 1
      resources/assets/js/main/components/project/todo/complete.vue
  34. 1 1
      resources/assets/js/main/components/project/users.vue
  35. 1 1
      resources/assets/js/main/components/report/my.vue
  36. 1 1
      resources/assets/js/main/components/report/receive.vue
  37. 3 0
      resources/assets/js/main/pages/docs/edit.vue
  38. 69 0
      resources/assets/js/main/pages/index.vue
  39. 12 2
      resources/assets/js/main/pages/project.vue
  40. 28 7
      resources/assets/js/main/pages/project/panel.vue
  41. 10 2
      resources/assets/js/main/pages/team.vue
  42. 17 4
      resources/assets/js/main/pages/todo.vue
  43. 2 1
      resources/assets/sass/fonts-ft.scss
  44. BIN
      resources/assets/sass/fonts/zenicon.woff2
  45. 66 0
      resources/assets/sass/main.scss

+ 1 - 0
.env.docker

@@ -4,6 +4,7 @@ APP_KEY=
 APP_DEBUG=true
 APP_URL=http://localhost
 APP_PORT=80
+APP_PORT_SSL=443
 
 LOG_CHANNEL=stack
 

+ 4 - 1
app/Http/Controllers/Api/DocsController.php

@@ -624,7 +624,10 @@ class DocsController extends Controller
         ]);
         Docs::notice($id, [ 'type' => 'update' ]);
         //
-        return Base::retSuccess('保存成功!');
+        return Base::retSuccess('保存成功!', [
+            'sid' => $id,
+            'content' => Base::json2array($content),
+        ]);
     }
 
     /**

+ 34 - 1
app/Http/Controllers/Api/ProjectController.php

@@ -1619,6 +1619,7 @@ class ProjectController extends Controller
      * - attention: 添加关注
      * - subtask: 修改子任务
      * @apiParam {String} [content]         内容数据
+     * @apiParam {String} [mode]            【act=attention】时可选参数,clean表示不在提交的列表中则删除
      *
      * @throws \Throwable
      */
@@ -2031,8 +2032,9 @@ class ProjectController extends Controller
              * 添加关注
              */
             case 'attention': {
+                $mode = trim(Base::getPostValue('mode'));
                 $userArray  = explode(",", $content);
-                DB::transaction(function () use ($user, $task, $userArray) {
+                DB::transaction(function () use ($mode, $user, $task, $userArray) {
                     foreach ($userArray AS $uname) {
                         $uid = Users::username2id($uname);
                         if (empty($uid)) {
@@ -2069,6 +2071,37 @@ class ProjectController extends Controller
                             ]);
                         }
                     }
+                    if ($mode == 'clean') {
+                        $tempLists = Base::DBC2A(DB::table('project_users')
+                            ->select(['id', 'username'])
+                            ->where([
+                                'type' => '关注',
+                                'taskid' => $task['id'],
+                            ])
+                            ->whereNotIn('username', $userArray)
+                            ->lockForUpdate()
+                            ->get());
+                        foreach ($tempLists AS $tempItem) {
+                            if (DB::table('project_users')->where('id', $tempItem['id'])->delete()) {
+                                $uname = $tempItem['username'];
+                                DB::table('project_log')->insert([
+                                    'type' => '日志',
+                                    'projectid' => $task['projectid'],
+                                    'taskid' => $task['id'],
+                                    'username' => $uname,
+                                    'detail' => $uname == $user['username'] ? '取消关注' : '移出关注',
+                                    'indate' => Base::time(),
+                                    'other' => Base::array2string([
+                                        'type' => 'task',
+                                        'id' => $task['id'],
+                                        'title' => $task['title'],
+                                        'operator' => $user['username'],
+                                        'action' => 'unattention',
+                                    ])
+                                ]);
+                            }
+                        }
+                    }
                 });
                 $tempRow = Base::DBC2A(DB::table('project_users')->select(['username'])->where([ 'type' => '关注', 'taskid' => $task['id'] ])->get()->pluck('username'));
                 $upArray['follower'] = Base::array2string($tempRow);

+ 2 - 2
app/Http/Controllers/Api/UsersController.php

@@ -242,9 +242,9 @@ class UsersController extends Controller
         $profession = trim(Request::input('profession'));
         if ($profession) {
             if (mb_strlen($profession) < 2) {
-                return Base::retError('称不可以少于2个字!');
+                return Base::retError('职位/职称不可以少于2个字!');
             } elseif (mb_strlen($profession) > 20) {
-                return Base::retError('称最多只能设置20个字!');
+                return Base::retError('职位/职称最多只能设置20个字!');
             } else {
                 $array['profession'] = $profession;
             }

+ 9 - 4
bin/wookteam

@@ -24,11 +24,16 @@ class wookteamLoader
     }
 }
 
-$array = getopt('', ['port:']);
+$array = getopt('', ['port:', 'ssl:']);
+$data = [];
 if (isset($array['port'])) {
+    $data['APP_PORT'] = $array['port'] ?: '8080';
+}
+if (isset($array['ssl'])) {
+    $data['APP_PORT_SSL'] = $array['ssl'] ?: '4433';
+}
+if ($data) {
     $loader = new wookteamLoader();
-    $loader->modifyEnv([
-        'APP_PORT' => $array['port']
-    ]);
+    $loader->modifyEnv($data);
 }
 

+ 3 - 3
config/laravels.php

@@ -73,9 +73,9 @@ return [
         'log_file'           => storage_path(sprintf('logs/swoole-%s.log', date('Y-m'))),
         'log_level'          => 4,
         'document_root'      => base_path('public'),
-        'buffer_output_size' => 2 * 1024 * 1024,
-        'socket_buffer_size' => 128 * 1024 * 1024,
-        'package_max_length' => 4 * 1024 * 1024,
+        'buffer_output_size' => 50 * 1024 * 1024,
+        'socket_buffer_size' => 256 * 1024 * 1024,
+        'package_max_length' => 100 * 1024 * 1024,
         'reload_async'       => true,
         'max_wait_time'      => 60,
         'enable_reuse_port'  => true,

+ 2 - 0
database/seeds/UsersTableSeeder.php

@@ -22,6 +22,7 @@ class UsersTableSeeder extends Seeder
                 'id' => 1,
                 'identity' => ',admin,',
                 'token' => 'MUBhZG1pbkBPSHNKODhAMTU5MTM0Mzg1NUBzdkJ6UnU=',
+                'az' => 'D',
                 'username' => 'admin',
                 'nickname' => '大乔',
                 'userimg' => '',
@@ -43,6 +44,7 @@ class UsersTableSeeder extends Seeder
                 'id' => 2,
                 'identity' => ',admin,',
                 'token' => 'MkBzeXN0ZW1AQUExbHN2QDE1OTEzNDI2OTBAQlZ5Z005',
+                'az' => 'X',
                 'username' => 'system',
                 'nickname' => '小乔',
                 'userimg' => '',

+ 1 - 0
docker-compose.yml

@@ -5,6 +5,7 @@ services:
     image: nginx
     ports:
       - "${APP_PORT}:80"
+      - "${APP_PORT_SSL}:443"
     volumes:
       - ./docker/site.conf:/etc/nginx/conf.d/default.conf
       - ./:/var/www

+ 2 - 0
docker/site.conf

@@ -10,6 +10,8 @@ upstream swoole {
 server {
     listen 80;
 
+    include /var/www/docker/site/*.conf;
+
     # Don't forget to bind the host
     server_name wookteam.com;
     root /var/www/public;

+ 2 - 2
install/DOCKER.md

@@ -32,7 +32,7 @@ $ ./cmd build php
 $ ./cmd composer install
 $ ./cmd artisan key:generate
 $ ./cmd artisan migrate --seed
-$ ./cmd php bin/wookteam --port=8080
+$ ./cmd php bin/wookteam --port=8080 --ssl=4433
 $ ./cmd up -d
 $ ./cmd npm install
 $ ./cmd npm run prod
@@ -44,7 +44,7 @@ $ ./cmd restart
 ### 更换端口
 
 ```bash
-$ ./cmd php bin/wookteam --port=8080
+$ ./cmd php bin/wookteam --port=8080 --ssl=4433
 $ ./cmd up -d
 ```
 

+ 2 - 2
install/en/DOCKER.md

@@ -32,7 +32,7 @@ $ ./cmd build php
 $ ./cmd composer install
 $ ./cmd artisan key:generate
 $ ./cmd artisan migrate --seed
-$ ./cmd php bin/wookteam --port=8080
+$ ./cmd php bin/wookteam --port=8080 --ssl=4433
 $ ./cmd up -d
 $ ./cmd npm install
 $ ./cmd npm run prod
@@ -44,7 +44,7 @@ Installed, project url: **`http://IP:PORT`** (`PORT` is the parameter `8080` in
 ### Change port
 
 ```bash
-$ ./cmd php bin/wookteam --port=8080
+$ ./cmd php bin/wookteam --port=8080 --ssl=4433
 $ ./cmd up -d
 ```
 

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
     "name": "wookteam",
-    "version": "1.5.13",
+    "version": "1.5.14",
     "description": "WookTeam是一款轻量级的开源在线团队协作工具,提供各类文档工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM,知识库管理等工具。",
     "scripts": {
         "ide-helper": "php artisan ide-helper:generate",

+ 9 - 0
resources/assets/js/common.js

@@ -1556,6 +1556,15 @@
             }
             return $A.runNum((bytes / Math.pow(k, i)), 2) + ' ' + sizes[i];
         },
+
+        /**
+         * window宽度≤width参数返回true
+         * @param width
+         * @returns {boolean}
+         */
+        windowMaxWidth(width) {
+            return window.innerWidth <= width;
+        }
     });
 
     window.$A = $;

+ 21 - 0
resources/assets/js/main/components/ImgUpload.vue

@@ -31,7 +31,9 @@
                             :max-size="maxSize"
                             :format="['jpg', 'jpeg', 'gif', 'png']"
                             :default-file-list="defaultList"
+                            :on-progress="handleProgress"
                             :on-success="handleSuccess"
+                            :on-error="handleError"
                             :on-format-error="handleFormatError"
                             :on-exceeded-size="handleMaxSize"
                             :before-upload="handleBeforeUpload"
@@ -314,6 +316,10 @@
                     return {};
                 }
             },
+            uploadIng: {
+                type: Number,
+                default: 0
+            }
         },
         data () {
             return {
@@ -425,8 +431,13 @@
                 this.$refs.upload.fileList.splice(fileList.indexOf(item), 1);
                 this.$emit('input', this.$refs.upload.fileList);
             },
+            handleProgress() {
+                //开始上传
+                this.$emit('update:uploadIng', this.uploadIng + 1);
+            },
             handleSuccess (res, file) {
                 //上传完成
+                this.$emit('update:uploadIng', this.uploadIng - 1);
                 if (res.ret === 1) {
                     file.url = res.data.url;
                     file.path = res.data.path;
@@ -441,6 +452,10 @@
                 }
                 this.$emit('input', this.$refs.upload.fileList);
             },
+            handleError() {
+                //上传错误
+                this.$emit('update:uploadIng', this.uploadIng - 1);
+            },
             handleFormatError (file) {
                 //上传类型错误
                 this.$Modal.warning({
@@ -481,6 +496,12 @@
                     this.$refs.upload.handleClick()
                 }
             },
+            handleManual(file) {
+                //手动传file
+                if (this.handleBeforeUpload()) {
+                    this.$refs.upload.upload(file);
+                }
+            },
             browsePicture(path) {
                 //获取图片空间
                 this.browseVisible = true;

+ 29 - 5
resources/assets/js/main/components/MDEditor/index.vue

@@ -1,12 +1,18 @@
 <template>
     <div>
         <div class="mdeditor-box">
-            <MarkdownPro ref="md1" v-model="content" :height="height" :toolbars="toolbars" :is-custom-fullscreen="transfer" @on-custom="customClick"></MarkdownPro>
-            <img-upload ref="myUpload" class="teditor-upload" type="callback" @on-callback="editorImage" num="50" style="display:none;"></img-upload>
+            <MarkdownPro ref="md1" v-model="content" :height="height" :toolbars="toolbars" :is-custom-fullscreen="transfer" @on-custom="customClick" @on-upload-image="handleUploadImageUpload"></MarkdownPro>
+            <ImgUpload
+                ref="myUpload"
+                class="upload-control"
+                type="callback"
+                :uploadIng.sync="uploadIng"
+                @on-callback="editorImage"
+                num="50"/>
             <Upload
                 name="files"
                 ref="fileUpload"
-                class="teditor-upload"
+                class="upload-control"
                 :action="actionUrl"
                 :data="params"
                 multiple
@@ -18,13 +24,20 @@
                 :on-error="handleError"
                 :on-format-error="handleFormatError"
                 :on-exceeded-size="handleMaxSize"
-                :before-upload="handleBeforeUpload">
-            </Upload>
+                :before-upload="handleBeforeUpload"/>
         </div>
+        <Spin fix v-if="uploadIng > 0">
+            <Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
+            <div>{{$L('正在上传文件...')}}</div>
+        </Spin>
         <Modal v-model="transfer" class="mdeditor-transfer" footer-hide fullscreen transfer :closable="false">
             <div class="mdeditor-transfer-body">
                 <MarkdownPro ref="md2" v-if="transfer" v-model="content" :toolbars="toolbars" :is-custom-fullscreen="transfer" height="100%" @on-custom="customClick"></MarkdownPro>
             </div>
+            <Spin fix v-if="uploadIng > 0">
+                <Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
+                <div>{{$L('正在上传文件...')}}</div>
+            </Spin>
         </Modal>
         <Modal v-model="html2md" title="html转markdown" okText="转换成markdown" width="680" class-name="simple-modal" @on-ok="htmlOk" transfer>
             <Input type="textarea" v-model="htmlValue" :rows="14" placeholder="请输入html代码..." />
@@ -56,6 +69,12 @@
     .mdeditor-box {
         position: relative;
     }
+    .upload-control {
+        display: none;
+        width: 0;
+        height: 0;
+        overflow: hidden;
+    }
 </style>
 <script>
     import MarkdownPro from './pro';
@@ -213,6 +232,11 @@
                 document.body.appendChild(script);
             },
 
+            handleUploadImageUpload(file) {
+                //手动传图片
+                this.$refs.myUpload.handleManual(file);
+            },
+
             /********************文件上传部分************************/
 
             handleProgress() {

+ 24 - 16
resources/assets/js/main/components/TEditor.vue

@@ -3,14 +3,20 @@
         <div class="teditor-box" :class="[spinShow?'teditor-loadstyle':'teditor-loadedstyle']">
             <textarea ref="myTextarea" :id="id">{{ content }}</textarea>
             <Spin fix v-if="spinShow">
-                <Icon type="ios-loading" size=18 class="teditor-spin-icon-load"></Icon>
+                <Icon type="ios-loading" size=18 class="upload-control-spin-icon-load"></Icon>
                 <div>{{$L('加载组件中...')}}</div>
             </Spin>
-            <img-upload ref="myUpload" class="teditor-upload" type="callback" @on-callback="editorImage" num="50" style="margin-top:5px;height:26px;"></img-upload>
+            <ImgUpload
+                ref="myUpload"
+                class="upload-control"
+                type="callback"
+                :uploadIng.sync="uploadIng"
+                @on-callback="editorImage"
+                num="50"/>
             <Upload
                 name="files"
                 ref="fileUpload"
-                class="teditor-upload"
+                class="upload-control"
                 :action="actionUrl"
                 :data="params"
                 multiple
@@ -22,11 +28,10 @@
                 :on-error="handleError"
                 :on-format-error="handleFormatError"
                 :on-exceeded-size="handleMaxSize"
-                :before-upload="handleBeforeUpload">
-            </Upload>
+                :before-upload="handleBeforeUpload"/>
         </div>
         <Spin fix v-if="uploadIng > 0">
-            <Icon type="ios-loading" size=18 class="teditor-spin-icon-load"></Icon>
+            <Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
             <div>{{$L('正在上传文件...')}}</div>
         </Spin>
         <Modal v-model="transfer" class="teditor-transfer" @on-visible-change="transferChange" footer-hide fullscreen transfer>
@@ -36,6 +41,10 @@
             <div class="teditor-transfer-body">
                 <textarea :id="'T_' + id">{{ content }}</textarea>
             </div>
+            <Spin fix v-if="uploadIng > 0">
+                <Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
+                <div>{{$L('正在上传文件...')}}</div>
+            </Spin>
         </Modal>
     </div>
 </template>
@@ -62,6 +71,13 @@
     }
     .teditor-transfer {
         background-color: #ffffff;
+        .tox-toolbar {
+            > div:last-child {
+                > button:last-child {
+                    margin-right: 64px;
+                }
+            }
+        }
         .ivu-modal-header {
             display: none;
         }
@@ -111,15 +127,7 @@
         overflow: inherit;
         position: relative;
     }
-    .teditor-spin-icon-load {
-        animation: ani-teditor-spin 1s linear infinite;
-    }
-    @keyframes ani-teditor-spin {
-        from { transform: rotate(0deg);}
-        50%  { transform: rotate(180deg);}
-        to   { transform: rotate(360deg);}
-    }
-    .teditor-upload {
+    .upload-control {
         display: none;
         width: 0;
         height: 0;
@@ -158,7 +166,7 @@
                         'advlist autolink lists link image charmap print preview hr anchor pagebreak imagetools',
                         'searchreplace visualblocks visualchars code',
                         'insertdatetime media nonbreaking save table contextmenu directionality',
-                        'emoticons paste textcolor colorpicker imagetools codesample save'
+                        'emoticons paste textcolor colorpicker imagetools codesample'
                     ];
                 }
             },

+ 78 - 25
resources/assets/js/main/components/UserInput.vue

@@ -9,7 +9,14 @@
 
         <!--输入框区域-->
         <div class="user-id-input" ref="reference">
-            <Input v-model="nickName" :placeholder="placeholder" :disabled="disabled" icon="md-search" @on-click="searchEnter" @on-enter="searchEnter" @on-blur="searchEnter(true)">
+            <Input v-model="nickName"
+                   :placeholder="placeholder"
+                   :disabled="disabled"
+                   icon="md-search"
+                   @on-click="searchEnter"
+                   @on-enter="searchEnter"
+                   @on-blur="searchEnter(true)"
+                   @on-change="inputChange">
                 <div v-if="$slots.prepend !== undefined" slot="prepend"><slot name="prepend"></slot></div>
                 <div v-if="$slots.append !== undefined" slot="append"><slot name="append"></slot></div>
             </Input>
@@ -25,17 +32,22 @@
                 class="user-id-input-body"
                 :data-transfer="transfer"
                 v-transfer-dom>
-                <Table highlight-row
-                       v-if="searchShow"
-                       ref="myTable"
-                       size="small"
-                       class="user-id-input-table"
-                       :style="tableStyle"
-                       :columns="columns"
-                       :data="userLists"
-                       @on-row-click="userChange"
-                       @on-selection-change="userSelect"
-                       :no-data-text="noDataText"></Table>
+                <div class="user-id-input-table">
+                    <Table highlight-row
+                           v-if="searchShow"
+                           ref="myTable"
+                           size="small"
+                           class="tableSelection"
+                           :style="tableStyle"
+                           :columns="columns"
+                           :data="userLists"
+                           @on-row-click="userChange"
+                           @on-selection-change="userSelect"
+                           :no-data-text="noDataText"></Table>
+                    <div v-if="isConfirm&&searchShow" class="user-id-input-bottom">
+                        <Button type="primary" size="small" @click="onConfirm">{{$L('确定')}}</Button>
+                    </div>
+                </div>
             </div>
         </transition>
     </div>
@@ -75,20 +87,17 @@
         }
 
         .user-id-spin {
+            width: 14px;
+            height: 14px;
             position: absolute;
-            top: 0;
-            bottom: 0;
-            left: 0;
-            right: 0;
-            border-radius: 4px;
-            background-color: rgba(255, 255, 255, 0.26);
+            top: 50%;
+            right: 34px;
+            transform: translate(0, -50%);
+            display: flex;
+            align-items: center;
             > div {
-                width: 18px;
-                height: 18px;
-                position: absolute;
-                top: 50%;
-                left: 6px;
-                transform: translate(0, -50%);
+                width: 100%;
+                height: 100%;
             }
         }
     }
@@ -98,9 +107,12 @@
         z-index: 99999
     }
     .user-id-input-table {
+        display: flex;
+        flex-direction: column;
         border-radius: 4px;
         overflow: hidden;
         box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.1);
+        background-color: #ffffff;
 
         .ivu-table table {
             width: 100% !important;
@@ -126,6 +138,16 @@
                 padding-right: 2px;
             }
         }
+
+        .user-id-input-bottom {
+            padding: 8px;
+            display: flex;
+            align-items: center;
+            justify-content: flex-end;
+            > button {
+                font-size: 13px;
+            }
+        }
     }
 </style>
 <script>
@@ -199,6 +221,10 @@
                 spinShow: false,
                 skipSearch: false,
 
+                isConfirm: false,
+
+                tempName: '',
+
                 winStyle: {},
 
                 columns: [],
@@ -250,6 +276,7 @@
                 });
             }
             this.noDataText = this.$L("数据加载中.....");
+            this.isConfirm = this.$listeners['on-confirm'];
         },
         watch: {
             value (val) {
@@ -365,6 +392,23 @@
             }
         },
         methods: {
+            inputChange() {
+                const val = this.nickName;
+                this.spinShow = false;
+                this.tempName = '';
+                if (val != '') {
+                    setTimeout(() => {
+                        if (val == this.nickName && val != this.tempName) {
+                            this.searchEnter(false, (res) => {
+                                return val == this.nickName;
+                            });
+                        }
+                    }, 500)
+                } else {
+                    this.searchShow = false;
+                }
+            },
+
             handleShowPopper() {
                 if (this.timeout) clearTimeout(this.timeout);
                 this.timeout = setTimeout(() => {
@@ -398,7 +442,7 @@
                 this.spinShow = false;
             },
 
-            searchEnter(verify) {
+            searchEnter(verify, callback) {
                 if (this.disabled === true) {
                     return;
                 }
@@ -435,6 +479,7 @@
                 if (this.nobookid) {
                     where['nobookid'] = this.nobookid;
                 }
+                this.tempName = where.username;
                 this.noDataText = this.$L("数据加载中.....");
                 $A.apiAjax({
                     url: 'users/searchinfo',
@@ -453,6 +498,9 @@
                         this.noDataText = this.$L("数据加载失败!");
                     },
                     success: (res) => {
+                        if (typeof callback === "function" && callback(res) === false) {
+                            return;
+                        }
                         if (res.ret === 1) {
                             this.userLists = res.data;
                             this.userLists.forEach((item) => {
@@ -579,6 +627,11 @@
                     }
                 });
                 return narr;
+            },
+
+            onConfirm(e) {
+                this.searchShow = false;
+                this.$emit('on-confirm', e);
             }
         },
         mounted() {

+ 44 - 1
resources/assets/js/main/components/WHeader.vue

@@ -2,7 +2,16 @@
     <div class="w-header">
         <div v-if="tabActive" class="w-header-row">
             <div class="w-header-row-left">
-                <ul>
+                <Dropdown class="m768-show" @on-click="tabPage" trigger="click" transfer>
+                    <Icon type="md-menu" class="dropdown-menu"/>
+                    <DropdownMenu slot="list">
+                        <DropdownItem name="todo">{{$L('待办')}}</DropdownItem>
+                        <DropdownItem name="project">{{$L('项目')}}</DropdownItem>
+                        <DropdownItem name="docs">{{$L('知识库')}}</DropdownItem>
+                        <DropdownItem name="team">{{$L('团队')}}</DropdownItem>
+                    </DropdownMenu>
+                </Dropdown>
+                <ul class="m768-hide">
                     <li :class="tabActive==='todo'?'active':''">
                         <a href="javascript:void(0)" @click="tabPage('todo')"><i class="ft icon">&#xe89e;</i>{{$L('待办')}}</a>
                     </li><li :class="tabActive==='project'?'active':''">
@@ -17,6 +26,7 @@
             <div class="w-header-row-right">
                 <Dropdown class="right-info" trigger="click" @on-click="setRightSelect" placement="bottom-end" transfer>
                    <div>
+                       <UserImg class="userimg" :info="userInfo"/>
                        <span class="username">{{$L('欢迎您')}}, {{(userInfo.nickname || userInfo.username) || $L('尊敬的会员')}}</span>
                        <Icon type="md-arrow-dropdown"/>
                    </div>
@@ -280,6 +290,39 @@
                         transform: scale(0.9);
                         z-index: 1;
                     }
+                    .userimg {
+                        display: none;
+                        width: 26px;
+                        height: 26px;
+                        margin-top: 7px;
+                        vertical-align: top;
+                        border-radius: 50%;
+                    }
+                    .username {
+                        display: inline-block;
+                    }
+                }
+            }
+            @media (max-width: 768px) {
+                margin: 0 16px;
+                .w-header-row-left {
+                    .dropdown-menu {
+                        font-size: 28px;
+                        vertical-align: top;
+                        margin-top: 6px;
+                    }
+                }
+                .w-header-row-right {
+                    .right-info {
+                        padding-left: 8px;
+                        padding-right: 8px;
+                        .userimg {
+                            display: inline-block;
+                        }
+                        .username {
+                            display: none;
+                        }
+                    }
                 }
             }
         }

+ 1 - 1
resources/assets/js/main/components/docs/users.vue

@@ -6,7 +6,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/archived.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 2 - 2
resources/assets/js/main/components/project/gantt/index.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="project-gstc-gantt">
-        <GanttView :lists="lists" :menuWidth="260" :itemWidth="80" @on-change="updateTime" @on-click="clickItem"/>
-        <Dropdown class="project-gstc-dropdown-filtr" @on-click="tapProject">
+        <GanttView :lists="lists" :menuWidth="$A.windowMaxWidth(768) ? 180 : 260" :itemWidth="80" @on-change="updateTime" @on-click="clickItem"/>
+        <Dropdown class="project-gstc-dropdown-filtr" :style="$A.windowMaxWidth(768)?{left:'142px'}:{}" @on-click="tapProject">
             <Icon class="project-gstc-dropdown-icon" :class="{filtr:filtrProjectId>0}" type="md-funnel" />
             <DropdownMenu slot="list">
                 <DropdownItem :name="0" :class="{'dropdown-active':filtrProjectId==0}">{{$L('全部')}}</DropdownItem>

+ 1 - 1
resources/assets/js/main/components/project/header/archived.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/header/create.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/my/favor.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/my/join.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/my/manage.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/statistics.vue

@@ -25,7 +25,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 35 - 8
resources/assets/js/main/components/project/task/detail/DescEditor.vue

@@ -14,8 +14,18 @@
                 :placeholder="placeholder"
                 v-html="content"
                 @blur="handleBlur"></div>
-            <ImgUpload ref="myUpload" class="desc-editor-upload" type="callback" @on-callback="editorImage" num="50" style="margin-top:5px;height:26px;"></ImgUpload>
+            <ImgUpload
+                ref="myUpload"
+                class="desc-editor-upload"
+                type="callback"
+                :uploadIng.sync="uploadIng"
+                @on-callback="editorImage"
+                num="50"></ImgUpload>
         </div>
+        <Spin fix v-if="uploadIng > 0">
+            <Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
+            <div>{{$L('正在上传文件...')}}</div>
+        </Spin>
         <Modal v-model="transfer" class="desc-editor-transfer" @on-visible-change="transferChange" footer-hide fullscreen transfer>
             <div slot="close">
                 <Button type="primary" size="small">{{$L('完成')}}</Button>
@@ -23,6 +33,10 @@
             <div class="desc-editor-transfer-body">
                 <textarea :id="'T_' + id" :placeholder="placeholder">{{content}}</textarea>
             </div>
+            <Spin fix v-if="uploadIng > 0">
+                <Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
+                <div>{{$L('正在上传文件...')}}</div>
+            </Spin>
         </Modal>
     </div>
 </template>
@@ -42,6 +56,13 @@
 }
 .desc-editor-transfer {
     background-color: #ffffff;
+    .tox-toolbar {
+        > div:last-child {
+            > button:last-child {
+                margin-right: 64px;
+            }
+        }
+    }
     .ivu-modal-header {
         display: none;
     }
@@ -78,11 +99,16 @@
     position: relative;
     &:hover {
         .desc-editor-tool {
-            display: flex;
+            .tool-button {
+                opacity: 0.9;
+                &:hover {
+                    opacity: 1;
+                }
+            }
         }
     }
     .desc-editor-tool {
-        display: none;
+        display: flex;
         flex-direction: row;
         align-items: center;
         position: absolute;
@@ -91,13 +117,10 @@
         z-index: 2;
         .tool-button {
             font-size: 12px;
-            opacity: 0.9;
-            transition: all 0.3s;
+            opacity: 0;
+            transition: all 0.2s;
             margin-left: 5px;
             background-color: #ffffff;
-            &:hover {
-                opacity: 1;
-            }
         }
     }
     .desc-editor-load {
@@ -155,6 +178,7 @@ export default {
     data() {
         return {
             loadIng: 0,
+            uploadIng: 0,
 
             id: "tinymce_" + Math.round(Math.random() * 10000),
             content: '',
@@ -245,6 +269,9 @@ export default {
                     'insertdatetime media nonbreaking save table contextmenu directionality',
                     'emoticons paste textcolor colorpicker imagetools codesample'
                 ],
+                save_onsavecallback: (e) => {
+                    this.handleBlur(e);
+                },
                 menubar: isFull,
                 inline: !isFull,
                 inline_boundaries: false,

+ 190 - 70
resources/assets/js/main/components/project/task/detail/detail.vue

@@ -1,7 +1,6 @@
 <template>
-    <div class="project-task-detail-window" :class="{'task-detail-show': visible}">
-        <div class="task-detail-bg"
-             @click="$nextTick(()=>{visible=false})"></div>
+    <div v-if="detail.isassign!==true" class="project-task-detail-window" :class="{'task-detail-show': visible}">
+        <div class="task-detail-bg" @click="handleBgClose"></div>
         <div class="task-detail-main"
              @drop.prevent="commentPasteDrag($event, 'drag')"
              @dragover.prevent="commentDragOver(true)"
@@ -35,12 +34,24 @@
                 <ul class="detail-text-box">
                     <li v-if="detail.startdate > 0 && detail.enddate > 0" class="text-time detail-icon">
                         <span>{{$L('计划时间:')}}</span>
-                        <em>{{$A.formatDate("Y-m-d H:i", detail.startdate)}} {{$L('至')}} {{$A.formatDate("Y-m-d H:i", detail.enddate)}}</em>
-                        <em v-if="detail.overdue" class="overdue">[{{$L('已超期')}}]</em>
+                        <em>
+                            {{$A.formatDate("Y-m-d H:i", detail.startdate)}} {{$L('至')}} {{$A.formatDate("Y-m-d H:i", detail.enddate)}}
+                            <em v-if="detail.overdue" class="overdue">[{{$L('已超期')}}]</em>
+                        </em>
                     </li>
                     <li class="text-username detail-icon">
                         <span>{{$L('负责人:')}}</span>
-                        <em><UserView :username="detail.username"/></em>
+                        <template v-if="typeof detail.username!=='undefined'">
+                            <em v-if="detail.username"><UserView :username="detail.username" showimg/></em>
+                            <em v-else>
+                                <div class="uname-no">{{$L('暂无负责人')}}</div>
+                                <Button :loading="!!loadData.claim" class="uname-button" type="primary" size="small" @click="handleTask('claimb')">{{$L('认领任务')}}</Button>
+                            </em>
+                            <em v-if="detail.type=='assign' && !detail.reassign">
+                                <Button v-if="detail.username==$A.getUserName()" class="uname-button" type="success" size="small" @click="handleTask('reassign')">{{$L('确认接收')}}</Button>
+                                <div v-else class="uname-text">[{{$L('等待确认')}}]</div>
+                            </em>
+                        </template>
                     </li>
                     <li v-if="followerLength(detail.follower) > 0" class="text-follower detail-icon">
                         <span>{{$L('关注者:')}}</span>
@@ -152,32 +163,25 @@
                     <Button :loading="!!loadData.comment" :disabled="!commentText" type="primary" @click="handleTask('comment')">评 论</Button>
                 </div>
             </div>
-            <div class="detail-right">
-                <div class="cancel"><em @click="visible=false"></em></div>
-                <Dropdown trigger="click" class="block" @on-click="handleTask">
-                    <Button :loading="!!loadData.unfinished || !!loadData.complete" :icon="detail.complete?'md-checkmark-circle-outline':'md-radio-button-off'" class="btn">{{$L('标记')}}{{$L(detail.complete?'未完成':'已完成')}}</Button>
-                    <DropdownMenu slot="list">
-                        <DropdownItem name="unfinished">{{$L('标记未完成')}}<Icon v-if="!detail.complete" type="md-checkmark" class="checkmark"/></DropdownItem>
-                        <DropdownItem name="complete">{{$L('标记已完成')}}<Icon v-if="detail.complete" type="md-checkmark" class="checkmark"/></DropdownItem>
-                        <DropdownItem name="archived2">{{$L('完成并归档')}}<Icon v-if="detail.complete && detail.archived" type="md-checkmark" class="checkmark"/></DropdownItem>
-                    </DropdownMenu>
-                </Dropdown>
-                <Dropdown trigger="click" class="block" @on-click="handleTask">
+            <div v-if="detail.username" class="detail-right" :class="{'open-menu':openMenu}">
+                <Button v-if="detail.complete" :loading="!!loadData.unfinished" icon="md-checkmark-circle-outline" class="btn" @click="handleTask('unfinished')">{{$L('标记未完成')}}</Button>
+                <Button v-else :loading="!!loadData.complete" icon="md-radio-button-off" class="btn" @click="handleTask('complete')">{{$L('标记已完成')}}</Button>
+                <Dropdown trigger="click" class="block" @on-click="handleTask" @on-visible-change="handleSubwinToggle">
                     <Button :loading="!!loadData.level" icon="md-funnel" class="btn">{{$L('优先级')}}</Button>
                     <DropdownMenu slot="list">
                         <DropdownItem v-for="level in [1,2,3,4]" :key="level" :name="`level-${level}`" :class="`p${level}`">{{levelFormt(level)}}<Icon v-if="detail.level==level" type="md-checkmark" class="checkmark"/></DropdownItem>
                     </DropdownMenu>
                 </Dropdown>
-                <Poptip placement="bottom" class="block">
+                <Poptip placement="bottom" class="block" @on-popper-show="[handleUsernameShow(),handleSubwinToggle(true)]" @on-popper-hide="handleSubwinToggle(false)" transfer>
                     <Button :loading="!!loadData.username" icon="md-person" class="btn">{{$L('负责人')}}</Button>
                     <div slot="content">
                         <div style="width:280px">
                             {{$L('选择负责人')}}
-                            <UserInput :projectid="detail.projectid" :nousername="detail.username" :transfer="false" @change="handleTask('usernameb', $event)" :placeholder="$L('输入关键词搜索')" style="margin:5px 0 3px"></UserInput>
+                            <UserInput v-model="detail.newusername" :projectid="detail.projectid" :nousername="detail.username" :transfer="false" @change="handleTask('usernameb', $event)" :placeholder="$L('输入关键词搜索')" style="margin:5px 0 3px"></UserInput>
                         </div>
                     </div>
                 </Poptip>
-                <Poptip ref="timeRef" placement="bottom" class="block" @on-popper-show="handleTask('inittime')">
+                <Poptip ref="timeRef" placement="bottom" class="block" @on-popper-show="[handleTask('inittime'),handleSubwinToggle(true)]" @on-popper-hide="handleSubwinToggle(false)" transfer>
                     <Button :loading="!!loadData.plannedtime || !!loadData.unplannedtime" icon="md-calendar" class="btn">{{$L('计划时间')}}</Button>
                     <div slot="content">
                         <div style="width:280px">
@@ -196,13 +200,12 @@
                     </div>
                 </Poptip>
                 <Button icon="md-attach" class="btn" @click="handleTask('fileupload')">{{$L('添加附件')}}</Button>
-                <Poptip ref="attentionRef" v-if="detail.username == myUsername" placement="bottom" class="block" @on-popper-show="() => {$set(detail, 'attentionLists', followerToStr(detail.follower))}">
+                <Poptip ref="attentionRef" v-if="detail.username == myUsername" placement="bottom" class="block" @on-popper-show="[handleAttentionShow(),handleSubwinToggle(true)]" @on-popper-hide="handleSubwinToggle(false)" transfer>
                     <Button :loading="!!loadData.attention" icon="md-at" class="btn">{{$L('关注人')}}</Button>
                     <div slot="content">
                         <div style="width:280px">
                             {{$L('选择关注人')}}
-                            <UserInput :projectid="detail.projectid" :multiple="true" :transfer="false" v-model="detail.attentionLists" :placeholder="$L('输入关键词搜索')" style="margin:5px 0 3px"></UserInput>
-                            <Button :loading="!!loadData.attention" :disabled="!detail.attentionLists" class="btn" type="primary" style="text-align:center;width:72px;height:28px;font-size:13px" @click="handleTask('attention')">确 定</Button>
+                            <UserInput :projectid="detail.projectid" :multiple="true" :transfer="false" v-model="detail.attentionLists" :placeholder="$L('输入关键词搜索')" style="margin:5px 0 3px" @on-confirm="handleTask('attention', true)"></UserInput>
                         </div>
                     </div>
                 </Poptip>
@@ -212,9 +215,10 @@
                 <Button v-else :loading="!!loadData.unarchived" icon="md-filing" class="btn" @click="handleTask('unarchived')">{{$L('取消归档')}}</Button>
                 <Button :loading="!!loadData.delete" icon="md-trash" class="btn" type="error" ghost @click="handleTask('deleteb')">{{$L('删除')}}</Button>
             </div>
-            <div v-if="detailDragOver" class="detail-drag-over">
-                <div class="detail-drag-text">{{$L('拖动到这里添加附件至 %', detail.title)}}</div>
-            </div>
+            <div v-if="detail.complete" class="detail-complete"><Icon type="md-checkmark-circle-outline" /></div>
+            <div class="detail-menu" @click="openMenu=!openMenu"><Icon type="md-menu" size="24"/></div>
+            <div class="detail-cancel"><em @click="visible=false"></em></div>
+            <div v-if="detailDragOver" class="detail-drag-over"><div class="detail-drag-text">{{$L('拖动到这里添加附件至 %', detail.title)}}</div></div>
         </div>
     </div>
 </template>
@@ -237,6 +241,8 @@
 
                 visible: false,
 
+                subwinVisible: 0,
+
                 urlProjectid: 0,
 
                 bakData: {},
@@ -250,6 +256,8 @@
                 timeOptions: {},
 
                 myUsername: '',
+
+                openMenu: false,
             }
         },
         beforeCreate() {
@@ -550,6 +558,29 @@
                 });
             },
 
+            handleUsernameShow() {
+                this.$set(this.detail, 'newusername', '')
+            },
+
+            handleAttentionShow() {
+                this.$set(this.detail, 'attentionLists', this.followerToStr(this.detail.follower))
+            },
+
+            handleBgClose() {
+                if (this.subwinVisible > 0) {
+                    return;
+                }
+                this.visible = false;
+            },
+
+            handleSubwinToggle(visible) {
+                if (visible) {
+                    this.subwinVisible++;
+                } else {
+                    this.subwinVisible--;
+                }
+            },
+
             handleTask(act, eve) {
                 let ajaxData = {
                     act: act,
@@ -658,6 +689,18 @@
                         }
                         return;
 
+                    case 'claimb':
+                        this.$Modal.confirm({
+                            title: this.$L('认领任务'),
+                            content: this.$L('你确定认领任务“%”吗?', this.detail.title),
+                            onOk: () => {
+                                this.handleTask('claim', eve);
+                            }
+                        });
+                        return;
+
+                    case 'claim':
+                    case 'reassign':
                     case 'complete':
                     case 'unfinished':
                     case 'archived':
@@ -750,6 +793,7 @@
                         if (!this.detail.attentionLists) {
                             return;
                         }
+                        ajaxData.mode = eve ? 'clean' : '';
                         ajaxData.content = this.detail.attentionLists;
                         this.$refs.attentionRef.handleClose();
                         break;
@@ -975,8 +1019,7 @@
             transform: translateZ(0);
             .detail-left {
                 flex: 1;
-                padding-left: 8px;
-                padding-right: 20px;
+                padding: 0 8px;
                 overflow: auto;
                 .detail-h2 {
                     color: #172b4d;
@@ -1093,6 +1136,20 @@
                             &:before {
                                 content: "\E903";
                             }
+                            .uname-no {
+                                display: inline-block;
+                                color: #888888;
+                            }
+                            .uname-button {
+                                font-size: 12px;
+                                margin-left: 6px;
+                            }
+                            .uname-text {
+                                line-height: 24px;
+                                color: #666666;
+                                font-size: 12px;
+                                margin-left: 6px;
+                            }
                         }
                         &.text-follower {
                             &:before {
@@ -1144,7 +1201,8 @@
                                     opacity: 0.6;
                                 }
                             }
-                            &.overdue {
+                            &.overdue,
+                            > em.overdue{
                                 color: #ff0000;
                             }
                             &.unfinished {
@@ -1235,46 +1293,10 @@
                 }
             }
             .detail-right {
-                .cancel {
-                    text-align: right;
-                    width: auto;
-                    height: 38px;
-                    em {
-                        display: inline-block;
-                        width: 38px;
-                        height: 38px;
-                        cursor: pointer;
-                        border-radius: 50%;
-                        transform: scale(0.92);
-                        &:after,
-                        &:before {
-                            position: absolute;
-                            content: "";
-                            top: 50%;
-                            left: 50%;
-                            width: 2px;
-                            height: 20px;
-                            background-color: #EE2321;
-                            transform: translate(-50%, -50%) rotate(45deg) scale(0.6, 1);
-                            transition: all .2s;
-                        }
-                        &:before {
-                            position: absolute;
-                            transform: translate(-50%, -50%) rotate(-45deg) scale(0.6, 1);
-                        }
-                        &:hover {
-                            &:after,
-                            &:before {
-                                background-color: #ff0000;
-                                transform: translate(-50%, -50%) rotate(135deg) scale(0.6, 1);
-                            }
-                            &:before {
-                                background-color: #ff0000;
-                                transform: translate(-50%, -50%) rotate(45deg) scale(0.6, 1);
-                            }
-                        }
-                    }
-                }
+                margin: 38px 0 6px;
+                padding-left: 12px;
+                overflow-x: hidden;
+                overflow-y: auto;
                 .block {
                     display: block;
                     .p1 {
@@ -1306,13 +1328,79 @@
                     text-overflow: ellipsis;
                 }
             }
+            .detail-complete {
+                display: inline-block;
+                pointer-events: none;
+                position: absolute;
+                top: 6px;
+                right: 23%;
+                font-size: 72px;
+                color: #19be6b;
+                opacity: 0.2;
+                z-index: 1;
+            }
+            .detail-menu {
+                display: none;
+                position: absolute;
+                top: 10px;
+                right: 64px;
+                text-align: right;
+                width: auto;
+                height: 38px;
+                z-index: 5;
+                align-items: center;
+            }
+            .detail-cancel {
+                position: absolute;
+                top: 10px;
+                right: 20px;
+                text-align: right;
+                width: auto;
+                height: 38px;
+                z-index: 5;
+                em {
+                    display: inline-block;
+                    width: 38px;
+                    height: 38px;
+                    cursor: pointer;
+                    border-radius: 50%;
+                    transform: scale(0.92);
+                    &:after,
+                    &:before {
+                        position: absolute;
+                        content: "";
+                        top: 50%;
+                        left: 50%;
+                        width: 2px;
+                        height: 20px;
+                        background-color: #EE2321;
+                        transform: translate(-50%, -50%) rotate(45deg) scale(0.6, 1);
+                        transition: all .2s;
+                    }
+                    &:before {
+                        position: absolute;
+                        transform: translate(-50%, -50%) rotate(-45deg) scale(0.6, 1);
+                    }
+                    &:hover {
+                        &:after,
+                        &:before {
+                            background-color: #ff0000;
+                            transform: translate(-50%, -50%) rotate(135deg) scale(0.6, 1);
+                        }
+                        &:before {
+                            background-color: #ff0000;
+                            transform: translate(-50%, -50%) rotate(45deg) scale(0.6, 1);
+                        }
+                    }
+                }
+            }
             .detail-drag-over {
                 position: absolute;
                 top: 0;
                 left: 0;
                 right: 0;
                 bottom: 0;
-                z-index: 3;
+                z-index: 6;
                 background-color: rgba(255, 255, 255, 0.78);
                 display: flex;
                 align-items: center;
@@ -1335,5 +1423,37 @@
                 }
             }
         }
+        @media (max-width: 768px) {
+            .task-detail-main {
+                padding: 10px 12px 2px;
+                .detail-left {
+                    margin-top: 32px;
+                    .detail-icon {
+                        padding-left: 22px;
+                    }
+                }
+                .detail-right {
+                    transform: translate(200%, 0);
+                    position: absolute;
+                    top: 0;
+                    right: 0;
+                    bottom: 0;
+                    margin: 0;
+                    padding: 48px 18px;
+                    background: #ffffff;
+                    box-shadow: 0 1px 6px 0 rgba(32, 33, 36, 0.28);
+                    z-index: 4;
+                    transition: all 0.3s;
+                    border-top-right-radius: 4px;
+                    border-bottom-right-radius: 4px;
+                    &.open-menu {
+                        transform: translate(0, 0);
+                    }
+                }
+                .detail-menu {
+                    display: flex;
+                }
+            }
+        }
     }
 </style>

+ 1 - 1
resources/assets/js/main/components/project/task/files.vue

@@ -43,7 +43,7 @@
             <Table class="tableFill" ref="tableRef" :size="!simple?'default':'small'" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" @on-sort-change="sortChange" stripe></Table>
 
             <!-- 分页 -->
-            <Page v-if="lastPage > 1 || !simple" :simple="simple" class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page v-if="lastPage > 1 || !simple" :simple="simple || $A.windowMaxWidth(768)" class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
 
         </div>
     </drawer-tabs-container>

+ 1 - 1
resources/assets/js/main/components/project/task/lists.vue

@@ -50,7 +50,7 @@
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" @on-sort-change="sortChange" stripe></Table>
 
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
 
         </div>
     </drawer-tabs-container>

+ 1 - 1
resources/assets/js/main/components/project/todo/attention.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/todo/complete.vue

@@ -4,7 +4,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/project/users.vue

@@ -6,7 +6,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 1 - 1
resources/assets/js/main/components/report/my.vue

@@ -29,7 +29,7 @@
             <!-- 列表 -->
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
         <WDrawer v-model="addDrawerShow" maxWidth="900">
             <report-add :canload="addDrawerShow" :id="addDrawerId" @on-success="addDrawerSuccess"></report-add>

+ 1 - 1
resources/assets/js/main/components/report/receive.vue

@@ -31,7 +31,7 @@
             <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" @on-sort-change="sortChange" stripe></Table>
 
             <!-- 分页 -->
-            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer></Page>
+            <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total transfer :simple="$A.windowMaxWidth(768)"></Page>
         </div>
     </drawer-tabs-container>
 </template>

+ 3 - 0
resources/assets/js/main/pages/docs/edit.vue

@@ -799,6 +799,9 @@
                             },
                             success: (res) => {
                                 if (res.ret === 1) {
+                                    if (this.getSid() == res.data.sid) {
+                                        this.docContent = Object.assign({}, this.docContent, res.data.content);
+                                    }
                                     this.$Message.success(res.msg);
                                     this.historyNoDataText = '';
                                     if (this.hid != 0) {

+ 69 - 0
resources/assets/js/main/pages/index.vue

@@ -358,6 +358,75 @@
                 margin-left: 10px;
             }
         }
+
+        @media (max-width: 768px) {
+            .header {
+                .z-row {
+                    .header-col-sub {
+                        h2 {
+                            padding: 12px 0 0 12px;
+                            span {
+                                display: none;
+                            }
+                        }
+                    }
+                }
+            }
+            .welcome {
+                height: auto;
+                .banner {
+                    height: auto;
+                    .z-row {
+                        flex-direction: column;
+                        padding-bottom: 52px;
+                        > div {
+                            width: 90%;
+                            margin: 0 auto;
+                        }
+                    }
+                    h3 {
+                        font-size: 24px;
+                        width: auto;
+                    }
+                    img {
+                        max-width: 100%;
+                        height: auto;
+                    }
+                }
+                .second {
+                    height: 120px;
+                    display: flex;
+                    align-items: center;
+                    .z-row {
+                        height: auto;
+                        line-height: 36px;
+                        font-size: 16px;
+                        display: block;
+                        .z-6 {
+                            width: 30%;
+                            margin: 0 5%;
+                            white-space: nowrap;
+                        }
+                    }
+                }
+            }
+            .block {
+                flex-direction: column;
+                margin: 24px auto;
+                padding-top: 24px;
+                max-width: 90%;
+                border: 0;
+                > div {
+                    width: 96%;
+                    margin: 0 auto;
+                }
+                .wrap-left,
+                .wrap-right {
+                    margin: 6px 0;
+                    line-height: 28px;
+                }
+            }
+        }
     }
 </style>
 <script>

+ 12 - 2
resources/assets/js/main/pages/project.vue

@@ -13,7 +13,17 @@
                     </div>
                 </div>
                 <div class="w-nav-flex"></div>
-                <div class="w-nav-right">
+                <div class="w-nav-right m768-show">
+                    <Dropdown @on-click="handleProject" trigger="click" transfer>
+                        <Icon type="md-menu" size="18"/>
+                        <DropdownMenu slot="list">
+                            <DropdownItem name="myjoin">{{$L('参与的项目')}}</DropdownItem>
+                            <DropdownItem name="myfavor">{{$L('收藏的项目')}}</DropdownItem>
+                            <DropdownItem name="mycreate">{{$L('我管理的项目')}}</DropdownItem>
+                        </DropdownMenu>
+                    </Dropdown>
+                </div>
+                <div class="w-nav-right m768-hide">
                     <span class="ft hover" @click="handleProject('myjoin', null)"><i class="ft icon">&#xE75E;</i> {{$L('参与的项目')}}</span>
                     <span class="ft hover" @click="handleProject('myfavor', null)"><i class="ft icon">&#xE720;</i> {{$L('收藏的项目')}}</span>
                     <span class="ft hover" @click="handleProject('mycreate', null)"><i class="ft icon">&#xE764;</i> {{$L('我管理的项目')}}</span>
@@ -68,7 +78,7 @@
                 </li>
             </ul>
             <!-- 分页 -->
-            <Page v-if="listTotal > 0" class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" :pageSize="listPageSize" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[20,40,60,100]" placement="top" transfer show-elevator show-sizer show-total></Page>
+            <Page v-if="listTotal > 0" class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" :pageSize="listPageSize" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[20,40,60,100]" placement="top" transfer show-elevator show-sizer show-total :simple="$A.windowMaxWidth(768)"></Page>
         </w-content>
 
         <Modal

+ 28 - 7
resources/assets/js/main/pages/project/panel.vue

@@ -25,11 +25,25 @@
                             </DropdownMenu>
                         </Dropdown>
                     </span>
-                    <span class="ft hover" @click="openProjectDrawer('lists')"><i class="ft icon">&#xE89E;</i> {{$L('列表')}}</span>
-                    <span class="ft hover" :class="{active:projectGanttShow}" @click="projectGanttShow=!projectGanttShow"><i class="ft icon">&#59141;</i> {{$L('甘特图')}}</span>
-                    <span class="ft hover" @click="openProjectDrawer('files')"><i class="ft icon">&#xE701;</i> {{$L('文件')}}</span>
-                    <span class="ft hover" @click="openProjectDrawer('logs')"><i class="ft icon">&#xE753;</i> {{$L('动态')}}</span>
-                    <span class="ft hover" @click="openProjectSettingDrawer('setting')"><i class="ft icon">&#xE7A7;</i> {{$L('设置')}}</span>
+                    <span class="m768-show-i">
+                        <Dropdown @on-click="openProjectDrawer" trigger="click" transfer>
+                            <Icon type="md-menu" size="18"/>
+                            <DropdownMenu slot="list">
+                                <DropdownItem name="lists">{{$L('列表')}}</DropdownItem>
+                                <DropdownItem name="projectGanttShow">{{$L('甘特图')}}</DropdownItem>
+                                <DropdownItem name="files">{{$L('文件')}}</DropdownItem>
+                                <DropdownItem  name="logs">{{$L('动态')}}</DropdownItem>
+                                <DropdownItem name="openProjectSettingDrawer">{{$L('设置')}}</DropdownItem>
+                            </DropdownMenu>
+                        </Dropdown>
+                    </span>
+                    <span class="m768-hide-i">
+                        <span class="ft hover" @click="openProjectDrawer('lists')"><i class="ft icon">&#xE89E;</i> {{$L('列表')}}</span>
+                        <span class="ft hover" :class="{active:projectGanttShow}" @click="projectGanttShow=!projectGanttShow"><i class="ft icon">&#59141;</i> {{$L('甘特图')}}</span>
+                        <span class="ft hover" @click="openProjectDrawer('files')"><i class="ft icon">&#xE701;</i> {{$L('文件')}}</span>
+                        <span class="ft hover" @click="openProjectDrawer('logs')"><i class="ft icon">&#xE753;</i> {{$L('动态')}}</span>
+                        <span class="ft hover" @click="openProjectSettingDrawer('setting')"><i class="ft icon">&#xE7A7;</i> {{$L('设置')}}</span>
+                    </span>
                 </div>
             </div>
         </div>
@@ -41,7 +55,7 @@
                 draggable=".label-draggable"
                 :style="{visibility: projectGanttShow ? 'hidden' : 'visible'}"
                 :animation="150"
-                :disabled="projectSortDisabled"
+                :disabled="projectSortDisabled || $A.windowMaxWidth(768)"
                 @sort="projectSortUpdate(true)">
                 <div
                     v-if="projectLabel.length > 0"
@@ -76,7 +90,7 @@
                                 group="task"
                                 draggable=".task-draggable"
                                 :animation="150"
-                                :disabled="projectSortDisabled"
+                                :disabled="projectSortDisabled || $A.windowMaxWidth(768)"
                                 @sort="projectSortUpdate(false)"
                                 @remove="projectSortUpdate(false)">
                                 <div v-for="task in label.taskLists"
@@ -937,6 +951,13 @@
             },
 
             openProjectDrawer(tab) {
+                if (tab == 'projectGanttShow') {
+                    this.projectGanttShow = !this.projectGanttShow;
+                    return;
+                } else if (tab == 'openProjectSettingDrawer') {
+                    this.openProjectSettingDrawer('setting')
+                    return;
+                }
                 this.projectDrawerTab = tab;
                 this.projectDrawerShow = true;
             },

+ 10 - 2
resources/assets/js/main/pages/team.vue

@@ -13,7 +13,15 @@
                     </div>
                 </div>
                 <div class="w-nav-flex"></div>
-                <div class="w-nav-right">
+                <div class="m768-show w-nav-right">
+                    <Dropdown @on-click="handleUser" trigger="click" transfer>
+                        <Icon type="md-menu" size="18"/>
+                        <DropdownMenu slot="list">
+                            <DropdownItem name="add">{{$L('添加团队成员')}}</DropdownItem>
+                        </DropdownMenu>
+                    </Dropdown>
+                </div>
+                <div class="m768-hide w-nav-right">
                     <span class="ft hover" @click="handleUser('add')"><i class="ft icon">&#xE740;</i> {{$L('添加团队成员')}}</span>
                 </div>
             </div>
@@ -25,7 +33,7 @@
                     <!-- 列表 -->
                     <Table class="tableFill" ref="tableRef" :columns="columns" :data="lists" :loading="loadIng > 0" :no-data-text="noDataText" stripe></Table>
                     <!-- 分页 -->
-                    <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total></Page>
+                    <Page class="pageBox" :total="listTotal" :current="listPage" :disabled="loadIng > 0" @on-change="setPage" @on-page-size-change="setPageSize" :page-size-opts="[10,20,30,50,100]" placement="top" show-elevator show-sizer show-total :simple="$A.windowMaxWidth(768)"></Page>
                 </div>
             </div>
         </w-content>

+ 17 - 4
resources/assets/js/main/pages/todo.vue

@@ -13,7 +13,18 @@
                     </div>
                 </div>
                 <div class="w-nav-flex"></div>
-                <div class="w-nav-right">
+                <div class="w-nav-right m768-show">
+                    <Dropdown @on-click="handleTodo" trigger="click" transfer>
+                        <Icon type="md-menu" size="18"/>
+                        <DropdownMenu slot="list">
+                            <DropdownItem name="calendar">{{$L('待办日程')}}</DropdownItem>
+                            <DropdownItem name="complete">{{$L('已完成的任务')}}</DropdownItem>
+                            <DropdownItem name="attention">{{$L('我关注的任务')}}</DropdownItem>
+                            <DropdownItem name="report">{{$L('周报/日报')}}</DropdownItem>
+                        </DropdownMenu>
+                    </Dropdown>
+                </div>
+                <div class="w-nav-right m768-hide">
                     <span class="ft hover" @click="handleTodo('calendar')"><i class="ft icon">&#xE706;</i> {{$L('待办日程')}}</span>
                     <span class="ft hover" @click="handleTodo('complete')"><i class="ft icon">&#xE73D;</i> {{$L('已完成的任务')}}</span>
                     <span class="ft hover" @click="handleTodo('attention')"><i class="ft icon">&#xE748;</i> {{$L('我关注的任务')}}</span>
@@ -48,7 +59,7 @@
                                     group="task"
                                     draggable=".task-draggable"
                                     :animation="150"
-                                    :disabled="taskSortDisabled"
+                                    :disabled="taskSortDisabled || $A.windowMaxWidth(768)"
                                     @sort="taskSortUpdate"
                                     @remove="taskSortUpdate">
                                     <div v-for="task in taskDatas[index].lists" class="content-li task-draggable" :key="task.id" :class="{complete:task.complete}" @click="openTaskModal(task)">
@@ -136,6 +147,8 @@
                         display: flex;
                         flex-direction: column;
                         .todo-card-head {
+                            flex-grow:0;
+                            flex-shrink:0;
                             display: flex;
                             align-items: center;
                             padding: 0 10px;
@@ -311,7 +324,7 @@
                 }
             }
         }
-        @media (max-width: 780px) {
+        @media (max-width: 768px) {
             .todo-main {
                 height: auto;
                 .todo-ul {
@@ -324,7 +337,7 @@
                             right: 0;
                             left: 0;
                             bottom: 0;
-                            margin: 10px;
+                            margin: 6px;
                             display: flex;
                             flex-direction: column;
                             min-height: 320px;

Dosya farkı çok büyük olduğundan ihmal edildi
+ 2 - 1
resources/assets/sass/fonts-ft.scss


BIN
resources/assets/sass/fonts/zenicon.woff2


+ 66 - 0
resources/assets/sass/main.scss

@@ -181,6 +181,19 @@
                     }
                 }
             }
+            @media (max-width: 768px) {
+                margin: 0 16px;
+                span {
+                    margin: 0 8px 0 0;
+                }
+                span + span {
+                    margin: 0;
+                    padding-left: 8px;
+                }
+                .w-nav-left {
+                    padding-right: 12px;
+                }
+            }
         }
     }
 }
@@ -321,3 +334,56 @@
         color: #058ce4;
     }
 }
+
+.upload-control-spin-icon-load {
+    font-size: 18px;
+    animation: upload-control-spin-icon-animation 1s linear infinite;
+}
+
+@keyframes upload-control-spin-icon-animation {
+    from { transform: rotate(0deg);}
+    50%  { transform: rotate(180deg);}
+    to   { transform: rotate(360deg);}
+}
+
+.m768-show {
+    display: none;
+    @media (max-width: 768px) {
+        display: block;
+    }
+}
+
+.m768-show-i {
+    display: none;
+    @media (max-width: 768px) {
+        display: inline;
+    }
+}
+
+.m768-show-ib {
+    display: none;
+    @media (max-width: 768px) {
+        display: inline-block;
+    }
+}
+
+.m768-hide {
+    display: block;
+    @media (max-width: 768px) {
+        display: none;
+    }
+}
+
+.m768-hide-i {
+    display: inline;
+    @media (max-width: 768px) {
+        display: none;
+    }
+}
+
+.m768-hide-ib {
+    display: inline-block;
+    @media (max-width: 768px) {
+        display: none;
+    }
+}