Git Product home page Git Product logo

repo-list's Introduction

Hi! I'm Nelson Earle

About me

I am a...

  • ๐ŸŽ“ Computer Science student at the University of Missouri
  • ๐Ÿ–ฅ๏ธ Linux enthusiast
  • ๐Ÿง™ Bash wizard
  • ๐Ÿฆ€ rustacean

GitHub Stats

nelson137

Reach me

Email: nelson.earle137@gmail.com Linkedin: nelson-earle

repo-list's People

Contributors

nelson137 avatar

Watchers

 avatar

repo-list's Issues

Improve modal component ergonomics

Restructure modal (& trigger) components to make them easier and more ergonomic to use. Users of the modal component should not have to wrap the trigger in a <Modal>...</Modal>.

It might also be nice to have a generic Modal component that can take the name of the variant that forwards the props to the real modal component (with full type info).

Before

ComponentThatUsesModalX.svelte:

<script lang="ts">
  import Modal from 'svelte-simple-modal';
  import XModalTrigger from './XModalTrigger.svelte';
</script>

<Modal>
  <XModalTrigger />
</Modal>

XModalTrigger.svelte:

<script lang="ts">
  import type { Context } from 'svelte-simple-modal';
  import XModal from './XModal.svelte';

  const { open } = getContext<Context>('simple-modal');

  function on_click(event: ClickEvent) {
    open(
      XModal,
      { /* XModal props... */ },
      { /* modal config... */ },
    );
  }
</script>

<button on:click={on_click}>Open Modal</button>

XModal.svelte:

<p>Content</p>

Possible After

ComponentThatUsesModalX.svelte:

<script lang="ts">
  import XModal from './XModal.svelte';
</script>

<XModal />

XModal.svelte:

<script lang="ts">
  import { type Context, Modal } from 'svelte-simple-modal';
  import XModalContent from './XModalContent.svelte';

  const { open } = getContext<Context>('simple-modal');

  function on_click(event: ClickEvent) {
    open(
      XModalContent,
      { /* XModal props... */ },
      { /* modal config... */ },
    );
  }
</script>

<Modal>
  <button on:click={on_click}>Open Modal</button>
</Modal>

XModalContent.svelte:

<p>Content</p>

Fix: Empty list height

An empty list should be the same height as a list with 1 row.

Currently, it looks like the min height of lists doesn't account for top and bottom margin/padding.

List edit mode: reorder lists

Since the beginning of this application list order has been determined by order of creation (or by editing the app data by hand). Add a list order modal.

  • Add a button in the edit mode controls.
  • The button opens a modal.
    • The modal has a vertical list of all the repo lists.
    • The lists can be dragged and dropped to reorder them. This defines the order of the lists.
    • On submission, the repo lists move to their new location.

Log errors on API endpoint failure

Currently, when an API endpoint fails and returns a non-success code, it does so silently. When this occurs (usage of endpoint_err()) it should be logged to the console.

(Better) Non-browser drag & drop

Rework drag & drop (DND) to be JS-only, not using the browser's API. This will open the door for more and better features due to the browser's DND limitations.

A promising library is Svelte DND Action which claims to be "production ready". It appears to be rich enough in features to support what I want.

Stricter lint rules & prettier

  • Investigate prettier and eslint configs.
  • Set more options, and inherit from defaults if some exist.
  • Fix code that violates rules.

Global button styles

All buttons have the same set of styles that remove the browser's defaults:

  • background-color: transparent
  • border: none
  • padding: 0px

Put these in the global CSS and deduplicate the styles.

Add component tests

Add playwright tests for UI components.

Will these have to be run separately from the current unit tests that use Vitest? Can they be run together?

List edit mode: move list delete into edit mode

Now that there is an edit mode that encapsulates some editing functionality, as much of the other editing functionality as makes sense should be moved to it as well.

Move the delete list functionality into edit mode.

The delete button should only be visible when in edit mode, to the right of the add repo button.

List edit mode: detect when dirty

Edit mode in the repo lists store is working great but is a little rigid. If you enter edit mode and immediately refresh the page you still get the unsaved changes popup. The store should track its dirty state and that should be used for the popup.

Implementation

Implement hashing for the entire store data and track it on edit mode change.

  • When entering edit mode a "backup" of the store is saved. Also calculate and save a hash.
  • Track the current state hash while in edit mode. Update it on change.
  • Store is "dirty" when the current state hash is not equal to the backup hash.

Fix: Handle duplicate repos

Dropping a repo on a list that already has it causes a bug. The duplicate repo ID is added to the list but this causes errors for svelte rendering due to the repos being in a keyed each.

UI

The UI should prevent a duplicate repo from being added to a list with some visual indicator.

Enable the "disabled layer" on the list while dragging over it like done with the All Repos list.

Store

The store should also prevent this from happening (if the UI logic doesn't sufficiently prevent it).

If the ID is already in the list, then throw an exception.

Maybe it's also worth having an extra safeguard on store load/write. On deserialization, we can manually implement Lodash's keyBy that warns and skips duplicates. On serialization, we can unique the list by running it through a Set.

List edit mode: simple edit mode

Add an edit button next to the profile menu that enables edit mode.

This is a large feature that will be broken down into several issues. This one just sets up the edit mode and moves existing edit functionality (add repos button) into it.

In edit mode, the edit button is replaced with edit controls. This is a submit button and a cancel button. List controls are also replaced with edit list controls. For now, this is just the add repos button. All list changes (repo rearranging & adding) are postponed until the edit is submitted.

Acceptance Criteria

  • (Global) Edit button puts lists in edit mode
  • List controls change when in edit mode
    • Delete button disappears
    • Replaced with add repos button
  • Stores (app global & persistent) are not updated until the edit is submitted
    • Clicking the cancel button reverts everything back to exactly how it was before editing
  • Repos can only be dragged while in edit mode

Better algorithm to calculate drop location

The current algorithm for determining where to insert a card that's about to be dropped into a list is simple: find the card in the list that is closest to the mouse, and the side of it that is closest to the mouse. If the closest side is the left/right of a card then the dragged card is inserted before/after it. This works well in most cases, except when dragging in the trailing gap of a list -- when there aren't enough cards to fill all columns of the last row:

In this situation, the most intuitive behavior is for the calculated drop location to be the end of the list (index=3) despite the fact that the right side of the second card (index=2) is closest to the mouse.

Investigation: UI redesign with a component library

Creating UIs from scratch is fun but it's hard work, and I'm no designer. Reworking the UI with a component library will make it look much cleaner and more polished, adding new elements will be much faster, and everything will be much more accessible.

There are a lot of good choices, here are the ones I've picked out (ranked):

  1. SvelteUI
    • โœ… modern look and feel
    • โœ… lots of highly-configurable components
  2. AgnosticUI
    • โœ… lots of components
    • โœ… really good accessibility
  3. Attractions
    • โœ… modern, unique look and feel
    • โŒ doesn't support Svelte 4 (๐Ÿ›‘ blocker)
    • โŒ project is inactive
  4. Sveltestrap
    • โŒ doesn't support Svelte 4 (๐Ÿ›‘ blocker)
  5. Svelte Material UI
    • โœ… based on a mature library (material) with many components
    • โŒ material is very popular with a recognizable style, will look more "stock"
  6. Skeleton UI
    • โœ… supports (custom & prebuilt) themes with a global light/dark-mode switch component
    • โŒ uses tailwind which is more difficult to integrate

Colors

Once a component library is integrated into the app, it would be good to have a comprehensive theme. Some of the libraries have built-in support for themes:

The others will likely require a custom (or another 3rd-party) solution.

Here's a useful palette generator tool (made for tailwind but can be useful regardless).

Separate lists & repos into 2 stores

For the POC it made sense to have one global store with all app data. Now that there is more data and there are more stores it makes the most sense to separate them.

List edit mode: repo cards are links

Now that repos can only be moved in edit mode -- and it doesn't make much sense to allow navigation to a repo in edit mode -- the link UX can be simplified. The cards themselves can be links. Clicking anywhere in a card (not just on the name) will navigate to the repo in GH. Hovering on the card should underline the name to indicate available user interaction.

This will make for a smoother UX because currently, to navigate to a repo, you have to click on the little icon that appears on hover.

List edit mode: bulk delete

Now that there is an edit mode there needs to be a way to remove repos from a list (I know, it's still not a feature yet).

When in edit mode a checkbox appears on each repo (where the navigate button used to be). Repo selection is tracked individually by each list. This means that each list has a delete button that only appears when repos are selected. The button only deletes repos in that list.

List edit mode: move new list into edit mode

Now that there is an edit mode that encapsulates some editing functionality, as much of the other editing functionality as makes sense should be moved to it as well.

Move the create new list functionality into edit mode.

The new list button should only be visible when in edit mode, to the left of the global edit mode controls in the header. There should be a vertical divider separating it from the submit and cancel buttons.

Make the header sticky

Repo cards are big, and having multiple lists quickly makes the page much taller than the viewport, meaning the header will not be in the viewport a lot of the time. Now that more functionality lives in the header, having it always visible is more desirable.

For now, simply making the header sticky to the top of the viewport is good enough. Eventually, it may be desired to have it collapse when scrolling down and re-open when the user starts to scroll up.

Better card reordering animation

Currently, when a card is dropped within a list to reorder, on drop it snaps back to its original position and they all animate at the same time to their new position. This is fine, but it could be better.

Instead, the card should animate directly from the mouse to its new position.

Possible implementation

The card is replaced with an invisible one and absolutely positioned to the mouse.

  • On drag, the card is replaced with the invisible placeholder.
  • On drop, the placeholder is removed and all cards animate to their new position.

This is certainly more complex than it sounds. Will the browser drag & drop play well with cards being absolutely positioned out of the list? What if they have to be removed as a child element for this to work? Will the FLIP animation work as expected moving the card back into the list? Will this affect other animations (e.g. moving cards between lists)?

List edit mode: prevent text select on repos

Now that cards are only draggable in edit mode, attempting to drag a card will select the text. Disable this with user-select: none.

Although, we may want to allow selecting repo names as that might be expected behavior.

Add debug buttons

Add buttons, that will be present only in development mode, that populate hard-coded data. This will be helpful for testing.

Buttons

  • Clear: delete all data
  • Demo: populate several demo lists with varying amounts of repos

Fix: Make list edit control styles more consistent

The styling of the edit controls on each repo list is inconsistent. Make them more uniform.

Inconsistencies:

  • Size
  • Default stroke
  • Hover stroke

Additionally, there are now 2 buttons that appear when repos are selected. These should be separated from the rest by a divider. Maybe their (dis)appearance should be animated, too.

Move components close to their routes

Due to Svelte's directory-based routing components can be kept in src/routes. Move non-shared UI components to be with their routes to clean up the lib directory.

Use wasm-git for data storage

Data kept in local storage can easily be lost. And while it was a good solution for a POC, it would be very annoying to have local storage cleared. Instead, use wasm-git to store app data in a git repo on GitHub.

A simple solution is to commit-and-push the lists on each update. But this could generate too much traffic so it might be better to let changes build up in a queue and sync/autosave on a fixed interval (e.g. 30s). With the latter, it would be best to also provide a save button for the user that dynamically updates to show the save state.

Save states for a dynamic autosave button:

  • disabled for no unsaved changes
  • enabled for unsaved changes
  • disabled with spinner while saving (from autosave or user click)

Extract all submit & cancel buttons into shared components

There are several sets of submit/accept/yes & cancel/no buttons, all with slightly different styling:

  • Edit mode controls in the header (icon only, color icon on hover)
  • Add repos modal (icon only, colored square background on hover)
  • Delete list modal (circle outline, colored background on hover)

and there may be more in the future.

Extract these 2 buttons into $lib/ui so that they can be reused.

Things to consider

  • Should we provide a styling API that allows the user to customize its appearance?
  • Should we limit the number of different styles and be more consistent?

Remove the special All Repos list

Like local storage (#1), this was simple and simple and easy for a POC but it is cumbersome to deal with in practice.

  • It adds noise to the UI -- taking up a lot of space for those of us with many repositories.
  • It complicates the logic requiring special handling -- it isn't kept in storage with the lists so it must be injected on deserialization and removed on serialization.
  • Likewise, it complicates the tests.

A better solution is to have a button on each list that opens a multi-select modal to choose repos to add to the list.

There are 2 good libraries I've found that provide a multi-select component:

Make list edit controls more interactive

Some of the buttons have consistent styling to indicate their interactivity. On hover, they change color or get brighter. However, some buttons don't: the edit controls on each list produce no style change on hover. They feel a bit "static" and unresponsive.

Make some style change on hover for the edit controls on each list so that they are more interactive.

Better create list button

The current create list button isn't very obvious or pretty.

Maybe the button should be a mini card with a dashed border.

Overhaul modals with SvelteUI

Now that SvelteUI has been introduced into the codebase with #24 we can start overhauling parts of the app with SvelteUI.

Rebuild the 3 modals with SvelteUI:

  • Create list
  • Delete list
  • Add repos to list

List edit mode: rename list

Now that the core edit functionality has been implemented within the new edit mode, it's time to move on to other things.

Add an edit button next to each list title. Clicking the button switches the list header into title edit mode, where the title text element is replaced with an input that has a cancel and submit button to the right. The input should expand to fill the available space in the header.

List edit mode: bulk move

When in edit mode, repos in a list can be selected to bulk delete them from the list. It would also be useful to move repos to another list when reorganizing.

Add another button to the list edit controls that removes the repos from the current list and adds them to another. The button opens a select menu (similar to the add repos modal) that allows the user to select one target list. Like the bulk delete button, this button should only be visible when 1 or more repos are selected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.