Browse Source

Merge pull request #8518 from google/placeholder-tags

tags.html: Add ability to add and remove placeholder tags
Marc Foley 1 day ago
parent
commit
950f1b3ac6
1 changed files with 138 additions and 93 deletions
  1. 138 93
      .ci/tags.html

+ 138 - 93
.ci/tags.html

@@ -2,51 +2,88 @@
 <script src="https://unpkg.com/papaparse@5.4.1/papaparse.min.js"></script>
 <script src="https://unpkg.com/papaparse@5.4.1/papaparse.min.js"></script>
 <link rel="preconnect" href="https://fonts.googleapis.com">
 <link rel="preconnect" href="https://fonts.googleapis.com">
 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link href="https://cdn.jsdelivr.net/npm/daisyui@4.12.14/dist/full.min.css" rel="stylesheet" type="text/css" />
+<script src="https://cdn.tailwindcss.com"></script>
 
 
 
 
 <body>
 <body>
   <div id="app">
   <div id="app">
     <link v-for="family in uniqueFamilies" :href="familyLink(family)" rel="stylesheet">
     <link v-for="family in uniqueFamilies" :href="familyLink(family)" rel="stylesheet">
 
 
-    <h1>Google Fonts Tagger</h1>
+    <!-- Navbar -->
+    <div style="max-height: 3rem" class="navbar bg-base-100 fixed left-0 top-0 shadow">
+        <a class="btn btn-ghost btn-sm text-xl">GF Tagger</a>
+        <ul class="menu menu-horizontal px-1">
+          <li>
+            <details>
+              <summary>File</summary>
+              <ul class="shadow w-36">
+                <li><a @click="saveCSV">Export CSV</a></li>
+                <li><a @click="prCSV">Open PR</a></li>
+              </ul>
+            </details>
+          </li>
+          <li>
+            <details>
+              <summary>Edit</summary>
+              <ul class="shadow w-56">
+                <li><a @click="AddPlaceHolderTags">Insert placeholder tags</a></li>
+                <li><a @click="RemovePlaceHolderTags">Remove placeholder tags</a></li>
+              </ul>
+            </details>
+          </li>
+          <li>
+            <details>
+              <summary>{{ CurrentCategory }}</summary>
+              <ul class="shadow">
+                <div class="cont" style="max-height: 16rem; overflow: scroll">
+                  <li  v-for="category in sortedCategories()">
+                    <a @click="CurrentCategory = category">{{ category }}</a>
+                  </li>
+                </div>
+              </ul>
+            </details>
+          </li>
+          <li>
+            <form @submit.prevent="loadCSV">
+              <div class="join" style="padding-top: 12px;">
+                  <input class="join-item input input-sm input-bordered w-full max-w-xs" v-model="commit" required placeholder="refs/heads/main">
+                  <button class="join-item btn btn-sm">checkout</button>
+              </div>
+            </form>
+          </li>
+        </ul>
+    </div>    
 
 
-    <div id="panel">
-      <div class="panel-tile">
-        <form @submit.prevent="loadCSV">
-          <label>Checkout Commit:</label>
-          <input v-model="commit" required placeholder="refs/heads/main">
-          <button>Checkout</button>
-        </form>
-      <div style="border: 0.1px solid rgb(161, 161, 161); margin-bottom: 10pt; margin-top: 10pt;"></div>
-
-        <label>Current tag:</label>
-        <select v-model="CurrentCategory" style="max-width: 300px;">
-          <option v-for="category in sortedCategories()" :key="category" :value="category">
-            {{ category }}
-          </option>
-        </select>
-      </div>
+    <!-- Add font panel -->
+    <div id="panel" class="fixed top-20 right-0 bg-base-100 p-5 shadow">
       <div class="panel-tile">
       <div class="panel-tile">
         <form @submit.prevent="AddTag">
         <form @submit.prevent="AddTag">
-          <label>Add Tag:</label>
-          <input v-model="newTag" required placeholder="Tag Name">
-          <button>Add</button>
-        </form>
-      </div>
-      <div style="border: 0.1px solid rgb(161, 161, 161); margin-bottom: 10pt; margin-top: 10pt;"></div>
-
-      <div class="panel-tile">
+          <div class="label label-xs">
+            <span class="label-text label-xs">Add Tag</span>
+          </div>
+          <div class="join">
+            <input class="join-item input input-xs input-bordered w-full max-w-xs" v-model="newTag" required placeholder="/Expressive/Funky">
+            <button class="join-item btn btn-xs">Add</button>
+          </div>
+        </form> 
+        <div class="divider"></div>
         <form @submit.prevent="AddFamily">
         <form @submit.prevent="AddFamily">
-          <label>Add family:</label>
-          <input list="items" v-model="newFamily" required placeholder="Family Name">
-          <datalist id="items">
-            <option v-for="family in uniqueFamilies" :value="family">
-          </datalist>
-          <input v-model="newWeight" required placeholder="Score">
-          <button>Add</button>
+          <div class="label lavel-xs">
+            <span class="label-text label-xs">Add Family</span>
+          </div>
+          <div class="join">
+            <input class="join-item input input-xs input-bordered w-full max-w-xs" list="items" v-model="newFamily" required placeholder="Family Name">
+            <datalist id="items">
+              <option v-for="family in uniqueFamilies" :value="family">
+            </datalist>
+            <input class="join-item input input-xs input-bordered btn-square" v-model="newWeight" required placeholder="Score">
+            <button class="join-item btn btn-xs">Add</button>
+          </div>
         </form>
         </form>
       </div>
       </div>
-      <div style="border: 0.1px solid rgb(161, 161, 161); margin-bottom: 10pt; margin-top: 10pt;"></div>
+      <div class="divider"></div>
+
       <div class="panel-tile" style="max-height: 100px; overflow: scroll;">
       <div class="panel-tile" style="max-height: 100px; overflow: scroll;">
         <label>History</label>
         <label>History</label>
           <div v-if="isEdited">
           <div v-if="isEdited">
@@ -56,31 +93,14 @@
             <p style="font-size: 10pt;">No changes</p>
             <p style="font-size: 10pt;">No changes</p>
           </div>
           </div>
       </div>
       </div>
-      <div style="border: 0.1px solid rgb(161, 161, 161); margin-bottom: 10pt; margin-top: 10pt;"></div>
-      <div style="border: 0.1px solid rgb(161, 161, 161); margin-bottom: 10pt; margin-top: 10pt;"></div>
-      <div class="panel-tile">
-        <button @click="prCSV">Open Pull Request</button>
-        <button style="float: right;" @click="saveCSV">Save CSV</button>
-      </div>
-
     </div>
     </div>
 
 
     <div v-if="sortedFamilies.length === 0">
     <div v-if="sortedFamilies.length === 0">
       <p>No families found for this tag. Please add some</p>
       <p>No families found for this tag. Please add some</p>
     </div>
     </div>
-    <div class="item" v-for="family in sortedFamilies" :key="family.Family">
-      <div style="float: left; width: 150px;">
-        <b>{{ family.Family }}</b>
-      </div>
-      <div style="float: left; width: 100px;">
-        <input style="width: 50px;" v-model.lazy="family.Weight" @change="edited(family)" placeholder="family.Weight">
-        <button @click="removeFamily(family)">X</button>
-      </div>
-      <div v-if="ready" :style="familyStyle(family)" contenteditable="true">
-        {{ familyPangram(family) }}
-      </div>
-      <div v-else>
-        Loading...
+    <div class="mt-20">
+      <div class="item" v-for="family in sortedFamilies" :key="family.Family">
+        <family-item :family="family" :ready="ready" @edited="edited" @remove="removeFamily"></family-item>
       </div>
       </div>
     </div>
     </div>
 
 
@@ -88,7 +108,42 @@
 </body>
 </body>
 
 
 <script>
 <script>
-  
+  Vue.component('family-item', {
+    props: ['family', 'ready'],
+    template: `
+      <div class="item p-1">
+        <div class="join">
+          <b class="pr-2">{{ family.Family }}</b>
+          <input style="width: 3rem;" class="join-item input input-xs input-bordered btn-square"  v-model.lazy="family.Weight" @change="edited" placeholder="family.Weight">
+          <button class="btn btn-xs join-item pr-2" @click="removeFamily">X</button>
+          </div>
+          <div v-if="ready" :style="familyStyle" contenteditable="true">
+            {{ familyPangram }}
+          </div>
+        <div v-else>
+          Loading...
+        </div>
+        <div class="divider"></div>
+      </div>
+    `,
+    methods: {
+      edited() {
+        this.$emit('edited', this.family);
+      },
+      removeFamily() {
+        this.$emit('remove', this.family);
+      }
+    },
+    computed: {
+      familyPangram() {
+        return this.$root.familyPangram(this.family);
+      },
+      familyStyle() {
+        return `font-family: "${this.family.Family}", "Adobe NotDef"; font-size: 32pt;`;
+      }
+    }
+  });
+
   var app = new Vue({
   var app = new Vue({
     el: '#app',
     el: '#app',
     data() {
     data() {
@@ -256,12 +311,31 @@
         
         
         this.history.push(`+ ${newFamily.Family},${newFamily["Group/Tag"]},${newFamily.Weight}`);
         this.history.push(`+ ${newFamily.Family},${newFamily["Group/Tag"]},${newFamily.Weight}`);
       },
       },
+      AddPlaceHolderTags() {
+        this.isEdited = true;
+        const existingTags = this.sortedFamilies
+        let seen = new Set();
+        existingTags.forEach((family) => seen.add(family.Family));
+        const familiesToAdd = this.uniqueFamilies
+        familiesToAdd.forEach((family) => {
+          if (!seen.has(family)) {
+            this.Families.push({ Family: family, "Group/Tag": this.CurrentCategory, Weight: "" });
+          }
+        });
+        this.history.push(`+ Placeholder tags added for ${this.CurrentCategory}`);
+      },
+      RemovePlaceHolderTags() {
+        this.isEdited = true;
+        this.Families = this.Families.filter((family) => family.Weight !== "");
+        this.history.push(`- Placeholder tags removed for all categories`);
+      },
       removeFamily(Family) {
       removeFamily(Family) {
         this.isEdited = true;
         this.isEdited = true;
         this.Families = this.Families.filter((t) => t !== Family);
         this.Families = this.Families.filter((t) => t !== Family);
         this.history.push(`- ${Family.Family},${Family["Group/Tag"]},${Family.Weight}`);
         this.history.push(`- ${Family.Family},${Family["Group/Tag"]},${Family.Weight}`);
       },
       },
       familiesToCSV() {
       familiesToCSV() {
+        this.RemovePlaceHolderTags();
         this.Families = this.Families.filter((t) => t.Family !== "");
         this.Families = this.Families.filter((t) => t.Family !== "");
         // The sorting function used is case sensitive.
         // The sorting function used is case sensitive.
         // This means that "A" will come before "a".
         // This means that "A" will come before "a".
@@ -279,6 +353,7 @@
           {
           {
             columns: ["Family", "Group/Tag", "Weight"],
             columns: ["Family", "Group/Tag", "Weight"],
             skipEmptyLines: true,
             skipEmptyLines: true,
+            header: false
           }
           }
         ) + "\n";
         ) + "\n";
       },
       },
@@ -338,6 +413,15 @@
       }
       }
     } // methods
     } // methods
   )
   )
+  // close open navbar dropdowns when user clicks elsewhere
+  var details = [...document.querySelectorAll('details')];
+  document.addEventListener('click', function(e) {
+  if (!details.some(f => f.contains(e.target))) {
+    details.forEach(f => f.removeAttribute('open'));
+  } else {
+    details.forEach(f => !f.contains(e.target) ? f.removeAttribute('open') : '');
+  }
+})
 </script>
 </script>
 
 
 
 
@@ -346,43 +430,4 @@
       font-family: "Adobe NotDef";
       font-family: "Adobe NotDef";
       src: url(https://cdn.jsdelivr.net/gh/adobe-fonts/adobe-notdef/AND-Regular.ttf);
       src: url(https://cdn.jsdelivr.net/gh/adobe-fonts/adobe-notdef/AND-Regular.ttf);
   }
   }
-  #app {
-    font-family: "Roboto", Helvetica, Arial, sans-serif;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-    text-align: left;
-    color: #2c3e50;
-    margin-top: 60px;
-  }
-  #panel {
-    position: fixed;
-    top: 0;
-    right: 0;
-    padding: 10px;
-    background-color: white;
-    box-shadow: 3px 3px 3px lightgray;
-  }
-  .panel-tile {
-    margin-bottom: 10px;
-  }
-  .familyy {
-    padding-top: 10px;
-    padding-bottom: 10px;
-  }
-  .item {
-    margin-top: 10px;
-    padding-top: 10px;
-    padding-bottom: 10px;
-    border-top: 1px solid #000;
-  }
-  #edited-panel {
-    position: fixed;
-    left: 0px;
-    top: 0px;
-    width: 80px;
-    padding: 5px;
-    background-color: black;
-    color: white;
-    font-weight: bold;
-  }
 </style>
 </style>