Просмотр исходного кода

feat: 优化项目成员用户选择模态框,添加 Select2 支持及搜索功能

lanjianrong 1 неделя назад
Родитель
Сommit
9b25bac070
3 измененных файлов с 73 добавлено и 73 удалено
  1. 28 0
      app/public/css/main.css
  2. 29 58
      app/public/js/sp_setting_permission.js
  3. 16 15
      app/view/sp_setting/user_modal.ejs

+ 28 - 0
app/public/css/main.css

@@ -3764,3 +3764,31 @@ button.gy-stat:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
     white-space: normal;
     overflow-wrap: break-word;
 }
+
+#sel-batch .project-member-filters .select2-container {
+    font-size: .875rem;
+}
+#sel-batch .project-member-filters .select2-selection--single {
+    position: relative;
+    display: flex;
+    align-items: center;
+    height: calc(1.5em + .5rem + 2px);
+    border-color: #ced4da;
+    border-radius: .2rem;
+}
+#sel-batch .project-member-filters .select2-selection__rendered {
+    width: 100%;
+    padding-right: 44px;
+    line-height: 1.5;
+}
+#sel-batch .project-member-filters .select2-selection__clear {
+    position: absolute;
+    top: 0;
+    right: 20px;
+    height: 100%;
+    margin-right: 0;
+}
+#sel-batch .project-member-filters .select2-selection__arrow {
+    top: 0;
+    height: 100%;
+}

+ 29 - 58
app/public/js/sp_setting_permission.js

@@ -2,58 +2,27 @@ $(document).ready(() => {
     autoFlashHeight();
     // 选择账号
     const refreshUnitUsersHtml = function () {
-        const keyword = $('#sb-keyword').val();
+        const keyword = $('#sb-keyword').val().trim();
         const html = [];
         const select = $('#sel-batch-unit').val();
-        const selectGroup = accountGroup.find(x => { return x.name === select; });
-        if (selectGroup) {
-            const filter = keyword ? selectGroup.groupList.filter(x => {
-                return x.role.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0;
-            }) : selectGroup.groupList;
-            for (const u of filter) {
-                html.push(`<tr class="text-center">`);
-                html.push(`<td><input type="checkbox" name="sel-batch-check" id="${u.id}" unit="${selectGroup.name}" ${(u.select ? 'checked' : '')} ${u.sp_exist ? 'disabled' : ''}></td>`);
-                html.push(`<td>${u.name}</td>`);
-                html.push(`<td>${u.role}</td>`);
-                html.push(`<td>${u.company}</td>`);
-                html.push('<tr>');
-            }
-        }
-        const noCompanyAccount = accountList.filter(x => {
-            if (!x.company) return true;
-            const unit = accountGroup.find(y => { return y.name === x.company; });
-            if (unit) return false;
-            return keyword ? x.role.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0 : true;
-        });
-        for (const u of noCompanyAccount) {
-            html.push(`<tr class="text-center table-secondary">`);
-            html.push(`<td><input type="checkbox" name="sel-batch-check" id="${u.id}" unit="${selectGroup.name}" ${(u.select ? 'checked' : '')} disabled></td>`);
-            html.push(`<td>${u.name}</td>`);
-            html.push(`<td>${u.role}</td>`);
-            html.push(`<td>${u.company}</td>`);
-            html.push('<tr>');
-        }
-        const otherCompanyAccount = accountList.filter(x => {
-            if (!keyword) return false;
-            if (!x.company || x.company === selectGroup.name) return false;
-            const unit = accountGroup.find(y => { return y.name === x.company; });
-            if (!unit) return false;
-            return x.role.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0;
+        const users = accountList.filter(user => {
+            if (select && user.company !== select) return false;
+            return !keyword || (user.role || '').indexOf(keyword) >= 0 || (user.name || '').indexOf(keyword) >= 0;
         });
-        for (const u of otherCompanyAccount) {
-            html.push(`<tr class="text-center table-secondary">`);
-            html.push(`<td><input type="checkbox" name="sel-batch-check" id="${u.id}" unit="${selectGroup.name}" ${(u.select ? 'checked' : '')} disabled></td>`);
+        const selectableUsers = users.filter(user => !user.sp_exist);
+        for (const u of users) {
+            html.push('<tr class="text-center">');
+            html.push(`<td><input type="checkbox" name="sel-batch-check" id="${u.id}" ${(u.select ? 'checked' : '')} ${u.sp_exist ? 'disabled' : ''}></td>`);
             html.push(`<td>${u.name}</td>`);
-            html.push(`<td>${u.role}</td>`);
-            html.push(`<td>${u.company}</td>`);
-            html.push('<tr>');
+            html.push(`<td>${u.role || ''}</td>`);
+            html.push(`<td>${u.company || ''}</td>`);
+            html.push('</tr>');
         }
         $('#sel-batch-users').html(html.join(''));
+        $('#sel-batch-all').prop('checked', selectableUsers.length > 0 && selectableUsers.every(user => user.select));
     };
     $('#sel-batch').on('show.bs.modal', function() {
-        accountGroup.forEach(ag => {
-            ag.groupList.forEach(u => { u.select = false; });
-        });
+        accountList.forEach(user => { user.select = false; });
         refreshUnitUsersHtml();
     });
     $('#sel-batch-unit').change(function() {
@@ -66,26 +35,21 @@ $(document).ready(() => {
         refreshUnitUsersHtml();
     });
     $('body').on('click', '[name=sel-batch-check]', function() {
-        const select = $('#sel-batch-unit').val();
-        const selectGroup = accountGroup.find(x => { return x.name === select; });
-        const user = selectGroup.groupList.find(x => { return x.id === parseInt(this.getAttribute('id')); });
+        const user = accountList.find(user => user.id === parseInt(this.getAttribute('id')));
+        if (!user || user.sp_exist) return;
         user.select = this.checked;
+        const checks = $('[name=sel-batch-check]:enabled');
+        $('#sel-batch-all').prop('checked', checks.length > 0 && checks.filter(':checked').length === checks.length);
     });
     $('#sel-batch-all').change(function() {
-        const select = $('#sel-batch-unit').val();
-        const selectGroup = accountGroup.find(x => { return x.name === select; });
-        selectGroup.groupList.forEach(x => {
-            x.select = x.sp_exist ? false : this.checked;
-        });
+        for (const check of $('[name=sel-batch-check]:enabled')) {
+            const user = accountList.find(user => user.id === parseInt(check.getAttribute('id')));
+            if (user) user.select = this.checked;
+        }
         refreshUnitUsersHtml();
     });
     $('#sel-batch-ok').click(() => {
-        const select = [];
-        for (const ag of accountGroup) {
-            for (const u of ag.groupList) {
-                if (u.select && !u.sp_exist) select.push(u.id);
-            }
-        }
+        const select = accountList.filter(user => user.select && !user.sp_exist).map(user => user.id);
         postData(`/sp/${spid}/setting/user/permission/update`, { add: select }, function() {
             window.location.reload();
         });
@@ -294,4 +258,11 @@ $(document).ready(() => {
             $('#copy-user-batch').modal('hide');
         });
     });
+    $('#sel-batch-unit').select2({
+        placeholder: '全部单位',
+        allowClear: true,
+        width: '300px',
+        dropdownParent: $('#sel-batch'),
+        minimumResultsForSearch: 0,
+    });
 });

+ 16 - 15
app/view/sp_setting/user_modal.ejs

@@ -1,3 +1,6 @@
+<link href="/public/css/bootstrap/select2.min.css" rel="stylesheet" />
+<link rel="stylesheet" href="/public/css/bootstrap/select2-bootstrap4.min.css">
+<script src="/public/js/bootstrap/select2.min.js"></script>
 <div class="modal fade" id="sel-batch" data-backdrop="static">
     <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content">
@@ -5,18 +8,8 @@
                 <h5 class="modal-title">添加账号至项目成员</h5>
             </div>
             <div class="modal-body">
-                <div class="d-flex justify-content-between mb-2">
-                    <div class="col">
-                        <div class="form-inline">
-                            <label for="inputPassword2" class="">单位:</label>
-                            <select class="form-control form-control-sm" style="width:300px" id="sel-batch-unit">
-                                <% for (const g of accountGroup) { %>
-                                <option value="<%- g.name %>"><%- g.name %></option>
-                                <% } %>
-                            </select>
-                        </div>
-                    </div>
-                    <div class="col-5">
+                <div class="d-flex align-items-center justify-content-between mb-2 project-member-filters">
+                    <div class="col-5 pl-0">
                         <div class="input-group input-group-sm">
                             <input type="text" class="form-control" placeholder="姓名/职位 搜索" aria-label="姓名/职位 搜索" id="sb-keyword" aria-describedby="sb-search">
                             <div class="input-group-append">
@@ -24,6 +17,17 @@
                             </div>
                         </div>
                     </div>
+                    <div class="col pr-0">
+                        <div class="d-flex align-items-center justify-content-end">
+                            <label for="sel-batch-unit" class="mb-0 text-nowrap">单位:</label>
+                            <select class="form-control form-control-sm" style="width:300px" id="sel-batch-unit">
+                                <option value="">全部单位</option>
+                                <% for (const g of accountGroup) { %>
+                                <option value="<%- g.name %>"><%- g.name %></option>
+                                <% } %>
+                            </select>
+                        </div>
+                    </div>
                 </div>
                 <div class="modal-height-500 scroll-y">
                     <table class="table table-bordered">
@@ -31,9 +35,6 @@
                         <tbody id="sel-batch-users"></tbody>
                     </table>
                 </div>
-                <div class="mt-3">
-                    <label class="form-text alert alert-danger">整行灰底显示的账号,请选择左上角的“单位”与之一致,即可勾选。</label>
-                </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>