Explorar el Código

show username hint

https://youtrack.weseek.co.jp/issue/GW-7773
- Move  showUsernameHint()  to changeHandler
- Move pattern variable definition
- Implement debounce to filter username
- Add username query to user list API
- Remove API result filtering
- Add findUserByUsernameRegex method to user model
- Implement findUserByUsernameRegex to /users/list API
I Komang Mudana hace 3 años
padre
commit
3f746a310f

+ 5 - 4
packages/app/src/components/PageEditor/CodeMirrorEditor.jsx

@@ -573,16 +573,17 @@ export default class CodeMirrorEditor extends AbstractEditor {
 
     this.updateCheatsheetStates(null, value);
 
+    // Show username hint on comment editor
+    if (this.props.isComment) {
+      this.commentMentionHelper.showUsernameHint();
+    }
+
   }
 
   keyUpHandler(editor, event) {
     if (event.key !== 'Backspace') {
       this.checkWhetherEmojiPickerShouldBeShown();
     }
-    // Show username hint on comment editor
-    if (this.props.isComment) {
-      this.commentMentionHelper.showUsernameHint();
-    }
   }
 
   /**

+ 19 - 11
packages/app/src/components/PageEditor/CommentMentionHelper.ts

@@ -1,5 +1,9 @@
+import { debounce } from 'throttle-debounce';
+
 import { apiv3Get } from '~/client/util/apiv3-client';
 
+const USERNAME_PATTERN = new RegExp(/@[A-Za-z0-9._-]{1,}/);
+
 export default class CommentMentionHelper {
 
   editor;
@@ -9,10 +13,11 @@ export default class CommentMentionHelper {
 
   constructor(editor) {
     this.editor = editor;
-    this.pattern = /@[A-Za-z0-9._-]{1,}/;
+    this.pattern = USERNAME_PATTERN;
+
   }
 
-  showUsernameHint = () => {
+  getUsernamHint = () => {
     const currentPos = this.editor.getCursor();
     const sc = this.editor.getSearchCursor(this.pattern, currentPos, { multiline:  false });
     if (sc.findPrevious()) {
@@ -30,23 +35,26 @@ export default class CommentMentionHelper {
       hint: async() => {
         const mention = this.editor.getDoc().getRange(sc.from(), sc.to());
         const username = mention.replace('@', '');
-        const users = await this.getUsersList(username);
-        return {
-          list: users,
-          from: sc.from(),
-          to: sc.to(),
-        };
+        if (username.length > 0) {
+          const users = await this.getUsersList(username);
+          return {
+            list: users,
+            from: sc.from(),
+            to: sc.to(),
+          };
+        }
       },
     });
   }
 
   getUsersList = async(username) => {
-    const { data } = await apiv3Get('/users/list');
+    const { data } = await apiv3Get('/users/list', { username });
     return data.users.map(user => ({
       text: `@${user.username} `,
       displayText: user.username,
-    }))
-      .filter(user => user.displayText.includes(username));
+    }));
   }
 
+showUsernameHint= debounce(800, () => this.getUsernamHint());
+
 }

+ 7 - 0
packages/app/src/server/models/user.js

@@ -715,6 +715,13 @@ module.exports = function(crowi) {
     return users;
   };
 
+  userSchema.statics.findUserByUsernameRegex = async function(username) {
+    const users = this.find({ username: { $regex: username, $options: 'i' } });
+    if (users.length === 0) {
+      throw new Error('No User found');
+    }
+    return users;
+  };
   class UserUpperLimitException {
 
     constructor() {

+ 7 - 3
packages/app/src/server/routes/apiv3/users.js

@@ -899,13 +899,17 @@ module.exports = (crowi) => {
    */
   router.get('/list', accessTokenParser, loginRequired, async(req, res) => {
     const userIds = req.query.userIds || null;
+    const username = req.query.username || null;
 
     let userFetcher;
-    if (!userIds || userIds.split(',').length <= 0) {
-      userFetcher = User.findAllUsers();
+    if (userIds !== null && userIds.split(',').length > 0) {
+      userFetcher = User.findUsersByIds(userIds.split(','));
+    }
+    else if (username !== null) {
+      userFetcher = User.findUserByUsernameRegex(username);
     }
     else {
-      userFetcher = User.findUsersByIds(userIds.split(','));
+      userFetcher = User.findAllUsers();
     }
 
     const data = {};