mirror of
				https://github.com/arcan1s/ffxivbis.git
				synced 2025-10-30 13:13:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			363 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			363 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html lang="en">
 | |
| <head>
 | |
|     <meta charset="UTF-8">
 | |
|     <title>Best in slot</title>
 | |
| 
 | |
|     <meta name="viewport" content="width=device-width, initial-scale=1">
 | |
| 
 | |
|     <link href="/static/favicon.ico" rel="shortcut icon">
 | |
| 
 | |
|     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" type="text/css">
 | |
|     <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css" rel="stylesheet" type="text/css">
 | |
| 
 | |
|     <link href="https://unpkg.com/bootstrap-table@1.19.1/dist/bootstrap-table.min.css" rel="stylesheet" type="text/css">
 | |
| 
 | |
| 
 | |
|     <link href="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" rel="stylesheet" type="text/css">
 | |
| 
 | |
|     <link href="/static/styles.css" rel="stylesheet" type="text/css">
 | |
| </head>
 | |
| <body>
 | |
| 
 | |
|     <div class="container">
 | |
|         <nav class="navbar navbar-expand-lg justify-content-between align-items-center border-bottom">
 | |
|             <a class="navbar-brand" id="navbar-title">Party</a>
 | |
|             <ul class="navbar-nav">
 | |
|                 <a class="nav-item nav-link" id="navbar-bis">best in slot</a>
 | |
|                 <a class="nav-item nav-link" id="navbar-loot">looted items</a>
 | |
|             </ul>
 | |
|             <ul class="navbar-nav">
 | |
|                 <a class="nav-item nav-link" id="navbar-users">users</a>
 | |
|             </ul>
 | |
|         </nav>
 | |
|     </div>
 | |
| 
 | |
|     <div id="alert-placeholder" class="container"></div>
 | |
| 
 | |
|     <div class="container">
 | |
|         <h2>Best in slot</h2>
 | |
|     </div>
 | |
| 
 | |
|     <div class="container">
 | |
|         <div id="toolbar">
 | |
|             <button id="update-btn" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#update-bis-dialog" hidden>
 | |
|                 <i class="bi bi-plus"></i> update
 | |
|             </button>
 | |
|             <button class="btn btn-secondary" onclick="reload()">
 | |
|                 <i class="bi bi-arrow-clockwise"></i> reload
 | |
|             </button>
 | |
|             <button id="remove-btn" class="btn btn-danger" onclick="removePiece()" disabled hidden>
 | |
|                 <i class="bi bi-trash"></i> remove
 | |
|             </button>
 | |
|         </div>
 | |
| 
 | |
|         <table id="bis" class="table table-striped table-hover"
 | |
|                data-click-to-select="true"
 | |
|                data-export-options='{"fileName": "bis"}'
 | |
|                data-page-list="[25, 50, 100, all]"
 | |
|                data-page-size="25"
 | |
|                data-pagination="true"
 | |
|                data-resizable="true"
 | |
|                data-search="true"
 | |
|                data-show-columns="true"
 | |
|                data-show-columns-search="true"
 | |
|                data-show-columns-toggle-all="true"
 | |
|                data-show-export="true"
 | |
|                data-show-fullscreen="true"
 | |
|                data-show-search-clear-button="true"
 | |
|                data-single-select="true"
 | |
|                data-sortable="true"
 | |
|                data-sort-name="nick"
 | |
|                data-sort-order="asc"
 | |
|                data-sort-reset="true"
 | |
|                data-toolbar="#toolbar">
 | |
|             <thead class="table-primary">
 | |
|             <tr>
 | |
|                 <th data-checkbox="true"></th>
 | |
|                 <th data-sortable="true" data-switchable="false" data-field="nick">nick</th>
 | |
|                 <th data-sortable="true" data-switchable="false" data-field="job">job</th>
 | |
|                 <th data-sortable="true" data-field="piece">piece</th>
 | |
|                 <th data-sortable="true" data-field="pieceType">piece type</th>
 | |
|             </tr>
 | |
|             </thead>
 | |
|         </table>
 | |
|     </div>
 | |
| 
 | |
|     <div id="update-bis-dialog" tabindex="-1" role="dialog" class="modal fade">
 | |
|         <div class="modal-dialog" role="document">
 | |
|             <form class="modal-content" action="javascript:" onsubmit="updateBis()">
 | |
|                 <div class="modal-header">
 | |
|                     <div class="btn-group" role="group" aria-label="Update bis">
 | |
|                         <input id="add-piece-btn" name="update-bis" type="radio" class="btn-check" autocomplete="off" checked>
 | |
|                         <label class="btn btn-outline-primary" for="add-piece-btn">add piece</label>
 | |
| 
 | |
|                         <input id="update-bis-btn" name="update-bis" type="radio" class="btn-check" autocomplete="off">
 | |
|                         <label class="btn btn-outline-primary" for="update-bis-btn">update bis</label>
 | |
|                     </div>
 | |
|                     <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
 | |
|                 </div>
 | |
| 
 | |
|                 <div class="modal-body">
 | |
|                     <div class="form-group row">
 | |
|                         <label class="col-sm-4 col-form-label" for="player">player</label>
 | |
|                         <div class="col-sm-8">
 | |
|                             <select id="player" name="player" class="form-control" title="player" required></select>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div id="piece-row" class="form-group row">
 | |
|                         <label class="col-sm-4 col-form-label" for="piece">piece</label>
 | |
|                         <div class="col-sm-8">
 | |
|                             <select id="piece" name="piece" class="form-control" title="piece"></select>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div id="piece-type-row" class="form-group row">
 | |
|                         <label class="col-sm-4 col-form-label" for="piece-type">piece type</label>
 | |
|                         <div class="col-sm-8">
 | |
|                             <select id="piece-type" name="pieceType" class="form-control" title="piece-type"></select>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div id="bis-link-row" class="form-group row" style="display: none">
 | |
|                         <label class="col-sm-4 col-form-label" for="bis-link">link</label>
 | |
|                         <div class="col-sm-8">
 | |
|                             <input id="bis-link" name="link" class="form-control" placeholder="link to bis">
 | |
|                         </div>
 | |
|                     </div>
 | |
| 
 | |
|                     <div class="modal-footer">
 | |
|                         <button type="button" class="btn btn-danger" data-bs-dismiss="modal">close</button>
 | |
|                         <button id="submit-add-bis-btn" type="submit" class="btn btn-primary">add</button>
 | |
|                         <button id="submit-set-bis-btn" type="submit" class="btn btn-primary" style="display: none">set</button>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </form>
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <div class="container">
 | |
|         <footer class="d-flex flex-wrap justify-content-between align-items-center border-top">
 | |
|             <ul class="nav">
 | |
|                 <li><a class="nav-link" href="/" title="home">home</a></li>
 | |
|             </ul>
 | |
| 
 | |
|             <ul class="nav">
 | |
|                 <li><a class="nav-link" href="https://github.com/arcan1s/ffxivbis" title="sources">ffxivbis</a></li>
 | |
|                 <li><a class="nav-link" href="https://github.com/arcan1s/ffxivbis/releases" title="releases list">releases</a></li>
 | |
|                 <li><a class="nav-link" href="https://github.com/arcan1s/ffxivbis/issues" title="issues tracker">report a bug</a></li>
 | |
|             </ul>
 | |
|         </footer>
 | |
|     </div>
 | |
| 
 | |
|     <script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
 | |
| 
 | |
|     <script src="https://unpkg.com/tableexport.jquery.plugin/tableExport.min.js"></script>
 | |
| 
 | |
|     <script src="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.min.js"></script>
 | |
| 
 | |
|     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
 | |
|     <script src="https://unpkg.com/bootstrap-table@1.19.1/dist/bootstrap-table.min.js"></script>
 | |
| 
 | |
|     <script src="https://unpkg.com/bootstrap-table@1.19.1/dist/extensions/export/bootstrap-table-export.min.js"></script>
 | |
| 
 | |
|     <script src="https://unpkg.com/bootstrap-table@1.19.1/dist/extensions/resizable/bootstrap-table-resizable.js"></script>
 | |
| 
 | |
|     <script src="/static/utils.js"></script>
 | |
|     <script src="/static/load.js"></script>
 | |
| 
 | |
|     <script>
 | |
|         const [partyId, isReadOnly] = getPartyId();
 | |
|         const table = $("#bis");
 | |
|         const removeButton = $("#remove-btn");
 | |
|         const updateButton = $("#update-btn");
 | |
| 
 | |
|         const submitAddBisButton = $("#submit-add-bis-btn");
 | |
|         const submitSetBisButton = $("#submit-set-bis-btn");
 | |
|         const updateBisDialog = $("#update-bis-dialog");
 | |
| 
 | |
|         const addPieceButton = $("#add-piece-btn");
 | |
|         const updateBisButton = $("#update-bis-btn");
 | |
| 
 | |
|         const bisLinkRow = $("#bis-link-row");
 | |
|         const pieceRow = $("#piece-row");
 | |
|         const pieceTypeRow = $("#piece-type-row");
 | |
| 
 | |
|         const linkInput = $("#bis-link");
 | |
|         const pieceInput = $("#piece");
 | |
|         const pieceTypeInput = $("#piece-type");
 | |
|         const playerInput = $("#player");
 | |
| 
 | |
|         function addPiece() {
 | |
|             const player = getCurrentOption(playerInput);
 | |
|             $.ajax({
 | |
|                 url: `/api/v1/party/${partyId}/bis`,
 | |
|                 data: JSON.stringify({
 | |
|                     action: "add",
 | |
|                     piece: {
 | |
|                         pieceType: pieceTypeInput.val(),
 | |
|                         job: player.dataset.job,
 | |
|                         piece: pieceInput.val(),
 | |
|                     },
 | |
|                     playerId: {
 | |
|                         partyId: partyId,
 | |
|                         nick: player.dataset.nick,
 | |
|                         job: player.dataset.job,
 | |
|                     },
 | |
|                 }),
 | |
|                 type: "POST",
 | |
|                 contentType: "application/json",
 | |
|                 success: function (_) { reload(); },
 | |
|                 error: function (jqXHR, _, errorThrown) { requestAlert(jqXHR, errorThrown); },
 | |
|             });
 | |
|             updateBisDialog.modal("hide");
 | |
|             return true; // action expects boolean result
 | |
|         }
 | |
| 
 | |
|         function hideControls() {
 | |
|             removeButton.attr("hidden", isReadOnly);
 | |
|             updateButton.attr("hidden", isReadOnly);
 | |
|         }
 | |
| 
 | |
|         function hideLinkPart() {
 | |
|             bisLinkRow.hide();
 | |
|             linkInput.prop("required", false);
 | |
|             submitSetBisButton.hide();
 | |
|             pieceRow.show();
 | |
|             pieceTypeRow.show();
 | |
|             pieceInput.prop("required", true);
 | |
|             pieceTypeInput.prop("required", true);
 | |
|             submitAddBisButton.show();
 | |
|         }
 | |
| 
 | |
|         function hidePiecePart() {
 | |
|             bisLinkRow.show();
 | |
|             linkInput.prop("required", true);
 | |
|             submitSetBisButton.show();
 | |
|             pieceRow.hide();
 | |
|             pieceTypeRow.hide();
 | |
|             pieceInput.prop("required", false);
 | |
|             pieceTypeInput.prop("required", false);
 | |
|             submitAddBisButton.hide();
 | |
|         }
 | |
| 
 | |
|         function reload() {
 | |
|             table.bootstrapTable("showLoading");
 | |
|             $.ajax({
 | |
|                 url: `/api/v1/party/${partyId}`,
 | |
|                 type: "GET",
 | |
|                 dataType: "json",
 | |
|                 success: function (data) {
 | |
|                     const items = data.map(function (player) {
 | |
|                         return player.bis.map(function (loot) {
 | |
|                             return {
 | |
|                                 nick: player.nick,
 | |
|                                 job: player.job,
 | |
|                                 piece: loot.piece,
 | |
|                                 pieceType: loot.pieceType,
 | |
|                             };
 | |
|                         });
 | |
|                     });
 | |
|                     const payload = items.reduce(function (left, right) { return left.concat(right); }, []);
 | |
|                     table.bootstrapTable("load", payload);
 | |
|                     table.bootstrapTable("uncheckAll");
 | |
|                     table.bootstrapTable("hideLoading");
 | |
| 
 | |
|                     const options = data.map(function (player) {
 | |
|                         const option = document.createElement("option");
 | |
|                         option.innerText = formatPlayerId(player);
 | |
|                         option.dataset.nick = player.nick;
 | |
|                         option.dataset.job = player.job;
 | |
|                         return option;
 | |
|                     });
 | |
|                     playerInput.empty().append(options);
 | |
|                 },
 | |
|                 error: function (jqXHR, _, errorThrown) { requestAlert(jqXHR, errorThrown); },
 | |
|             });
 | |
|         }
 | |
| 
 | |
|         function removePiece() {
 | |
|             const pieces = table.bootstrapTable("getSelections");
 | |
|             pieces.map(function (loot) {
 | |
|                 $.ajax({
 | |
|                     url: `/api/v1/party/${partyId}/bis`,
 | |
|                     data: JSON.stringify({
 | |
|                         action: "remove",
 | |
|                         piece: {
 | |
|                             pieceType: loot.pieceType,
 | |
|                             job: loot.job,
 | |
|                             piece: loot.piece,
 | |
|                         },
 | |
|                         playerId: {
 | |
|                             partyId: partyId,
 | |
|                             job: loot.job,
 | |
|                             nick: loot.nick,
 | |
|                         },
 | |
|                     }),
 | |
|                     type: "POST",
 | |
|                     contentType: "application/json",
 | |
|                     success: function (_) { reload(); },
 | |
|                     error: function (jqXHR, _, errorThrown) { requestAlert(jqXHR, errorThrown); },
 | |
|                 });
 | |
|             });
 | |
|         }
 | |
| 
 | |
|         function reset() {
 | |
|             if (updateBisButton.is(":checked")) {
 | |
|                 hidePiecePart();
 | |
|             }
 | |
|             if (addPieceButton.is(":checked")) {
 | |
|                 hideLinkPart();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         function setBis() {
 | |
|             const player = getCurrentOption(playerInput);
 | |
|             $.ajax({
 | |
|                 url: `/api/v1/party/${partyId}/bis`,
 | |
|                 data: JSON.stringify({
 | |
|                     link: linkInput.val(),
 | |
|                     playerId: {
 | |
|                         partyId: partyId,
 | |
|                         nick: player.dataset.nick,
 | |
|                         job: player.dataset.job,
 | |
|                     },
 | |
|                 }),
 | |
|                 type: "PUT",
 | |
|                 contentType: "application/json",
 | |
|                 success: function (_) { reload(); },
 | |
|                 error: function (jqXHR, _, errorThrown) { requestAlert(jqXHR, errorThrown); },
 | |
|             });
 | |
|             updateBisDialog.modal("hide");
 | |
|             return true; // action expects boolean result
 | |
|         }
 | |
| 
 | |
|         function updateBis() {
 | |
|             if (updateBisButton.is(":checked")) {
 | |
|                 return setBis();
 | |
|             }
 | |
|             if (addPieceButton.is(":checked")) {
 | |
|                 return addPiece();
 | |
|             }
 | |
|             return false; // should not happen
 | |
|         }
 | |
| 
 | |
|         $(function () {
 | |
|             setupFormClear(updateBisDialog, reset);
 | |
|             setupRemoveButton(table, removeButton);
 | |
| 
 | |
|             loadHeader(partyId);
 | |
|             loadTypes("/api/v1/types/pieces", pieceInput);
 | |
|             loadTypes("/api/v1/types/pieces/types", pieceTypeInput);
 | |
| 
 | |
|             hideControls();
 | |
| 
 | |
|             updateBisButton.click(function () { reset(); });
 | |
|             addPieceButton.click(function () { reset(); });
 | |
| 
 | |
|             table.bootstrapTable({});
 | |
|             reload();
 | |
|             reset();
 | |
|         });
 | |
|     </script>
 | |
| 
 | |
| </body>
 | |
| </html> |