1class AuthorshipTable { 2 3 constructor(entity, element) { 4 this.entity = entity; 5 this.element = element; 6 this.list = $(this.element).find('#author-list'); 7 this.search = $(this.element).find('#author-search'); 8 this.searchResults = $(this.element).find('#author-search-results'); 9 } 10 11 DoAuthorRow(authorship) { 12 let d = $('<div></div>').addClass('d-flex flex-row align-items-center border rounded my-1').text(authorship.name).attr('data-entity-type', 'author').attr('data-entity-id', authorship.author_id); 13 let img = $('<img>').attr('src', authorship.bio_pic).addClass('rounded-circle me-2 border').css({ 'max-height': '40px' }).prependTo(d); 14 let p = $('<a></a>').attr('href', '/author/' + authorship.author_id + '/view').attr('target', '_blank').addClass('bi-person btn ms-auto rounded-end-0').appendTo(d); 15 let grip = $('<grip></grip>').addClass('btn bi-arrows-vertical').attr('data-role', 'grip').prependTo(d); 16 let shadow = $('<button></button>').addClass('btn rounded-0').appendTo(d); 17 if (authorship.shadow_author == 1) { 18 shadow.removeClass('bi-eye').addClass('bi-eye-slash'); 19 } else { 20 shadow.removeClass('bi-eye-slash').addClass('bi-eye'); 21 } 22 shadow.on('click', async (event) => { 23 if ($(event.target).is('[disabled]')) return; 24 $(event.target).attr('disabled', true); 25 let shadow_author = ($(event.target).hasClass('bi-eye')) ? 1 : 0; 26 await ChangeAuthorVisibility(this.entity, $(event.target).closest('[data-entity-type="author"][data-entity-id]').attr('data-entity-id'), shadow_author); 27 $(event.target).toggleClass('bi-eye').toggleClass('bi-eye-slash'); 28 $(event.target).removeAttr('disabled'); 29 }); 30 let del = $('<button></button>').addClass('btn text-danger bi-x-lg rounded-start-0').appendTo(d); 31 del.on('click', async (event) => { 32 await RemoveAuthor(this.entity, $(event.target).closest('[data-entity-type="author"][data-entity-id]').attr('data-entity-id')); 33 $(event.target).off('click'); 34 $(event.target).parent().remove(); 35 }); 36 return d; 37 } 38 39 Render() { 40 this.list.empty(); 41 this.searchResults.empty(); 42 this.search.val(''); 43 for (let authorship of this.entity.authorships) { 44 this.list.append(this.DoAuthorRow(authorship)); 45 } 46 this.search.on('input', async (event) => { 47 clearTimeout(searchTimeout); 48 let v = $(event.target).val(); 49 if (v.length > 0) { 50 searchTimeout = setTimeout(async (event) => { 51 this.searchResults.empty(); 52 let results = await Search(v, ['authors'], 20, { method: 'show_all' }); 53 for (let id in results.authors) { 54 let authorship = results.authors[id]; 55 let b = $('<button></button>').text(authorship.name).addClass('btn btn-light text-start m-1 bi-plus-lg icon-text-link w-100').attr('data-entity-type', 'author').attr('data-entity-id', authorship.author_id); 56 this.searchResults.append(b); 57 b.on('click', async (event) => { 58 let author_id = $(event.target).closest('[data-entity-type="author"][data-entity-id]').attr('data-entity-id'); 59 let authorship = await AddAuthor(this.entity, author_id); 60 console.log(authorship); 61 switch (this.entity.type) { 62 case 'chapter': 63 this.entity = await GetChapterFromID(this.entity.id, true); 64 this.Render(); 65 break; 66 case 'book': 67 this.entity = await GetBook(this.entity.id, true); 68 this.Render(); 69 break; 70 } 71 }); 72 } 73 }, searchDelay); 74 } else { 75 this.searchResults.empty(); 76 } 77 }); 78 $(this.list).sortable({ 79 handle: 'grip[data-role="grip"]', 80 items: 'div[data-entity-id]', 81 axis: 'y', 82 revert: true, 83 scrollSpeed: 6, 84 opacity: 0.8, 85 update: async (event) => { 86 let e = event.target; 87 $(e).sortable('disable'); 88 let authors = []; 89 $(e).children('div[data-entity-id]').each(function () { 90 authors.push($(this).attr('data-entity-id')); 91 }); 92 try { 93 if (await SortAuthors(this.entity, authors)) { 94 Toast('Author Order Saved', 'The author order has been saved.', 'bg-success text-light'); 95 } 96 } finally { 97 $(e).sortable('enable'); 98 } 99 } 100 }); 101 } 102}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.