Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 32 additions & 44 deletions .github/tasks.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,36 @@
## Tasks
- [x] Read the description in [#164](https://github.com/SenteraLLC/ulabel/issues/164)
- [x] Read the description in [#234](https://github.com/SenteraLLC/ulabel/issues/234)
- [x] Write a clear summary of the requested change
- [x] Propose some options of how to proceed. Wait for user input to decide which to try first.
- [x] Break the requested feature down into concrete steps. Add the steps to the tasks list, and then start working on then one by one.

### Decision: Proceeding with Option 3 (Webpack modernization + dependency cleanup)
### Summary
Create an annotation list toolbox item that displays all annotations in a list format, similar to other annotation tools. The list should:
- Display each annotation (by ID or index)
- Allow show/hide of deprecated annotations (default: hide)
- Support grouping by class
- Enable clicking to "fly to" the annotation
- Show annotation labels/IDs (on hover or drawn on canvas)
- Display "current idx / total" when navigating through annotations
- Highlight annotations when hovering in the list

#### Step 1: Move dependencies to devDependencies
- [x] Move `@turf/turf` from dependencies to devDependencies
- [x] Move `jquery` from dependencies to devDependencies
- [x] Move `polygon-clipping` from dependencies to devDependencies
- [x] Move `uuidv4` from dependencies to devDependencies
- [x] Test: Run `npm install` and verify it works
- [x] Test: Run `npm run build` and verify output is identical (both files 1039.6 KB)

#### Step 2: Enable and modernize webpack minification ✅ COMPLETE
- [x] Remove commented-out UglifyJsPlugin code (deprecated)
- [x] Enable webpack 5's built-in TerserPlugin for minification
- [x] Configure it to only minify `ulabel.min.js`, not `ulabel.js`
- [x] Test: Run `npm run build` and verify both files are created
- [x] Test: Verify `ulabel.js` is NOT minified (readable) - 2.33 MB with webpack runtime and formatted code
- [x] Test: Verify `ulabel.min.js` IS minified (smaller size) - 1.02 MB minified
- [x] Test: Run `npm run lint` - No errors
- [x] Note: File size difference (2.33 MB vs 1.02 MB) is expected - readable version includes webpack runtime overhead

#### Step 3: Verify and document ✅ COMPLETE
- [x] Compare file sizes before/after
- Before: Both files 1039 KB (both minified, minification was disabled)
- After: ulabel.js 2.33 MB (readable), ulabel.min.js 1.02 MB (minified)
- Result: Minification now working correctly, file size increase for non-min version is expected
- [x] Update CHANGELOG.md with changes
- [x] Document any findings or recommendations

#### Step 4: Security and dependency updates ✅ COMPLETE
- [x] Run `npm audit` to identify vulnerabilities
- [x] Fix 12 vulnerabilities using `npm audit fix`
- [x] Apply breaking changes for remaining issues with `npm audit fix --force`
- [x] Update `typescript-eslint` packages to be compatible with ESLint 9.37.0
- [x] Fix linting issues in `tests/e2e/fixtures.js`
- [x] Verify all tests still pass (28 unit tests + 36 e2e tests)
- [x] Final audit: 0 vulnerabilities

#### Step 5: Configure package exports for minified by default ✅ COMPLETE
- [x] Update `main` and `module` fields to point to `dist/ulabel.min.js`
- [x] Add `exports` field with options: `.` (minified), `./min` (minified), `./debug` (unminified)
- [x] Update `unpkg` field to serve minified version by default
- [x] Update README.md with usage examples for both minified and unminified versions
- [x] Document clear import patterns for users
### Implementation Steps
- [x] 1. Research existing toolbox items and understand the toolbox structure
- [x] Read `src/toolbox.ts` to understand how toolbox items work
- [x] Review existing toolbox items in `src/toolbox_items/`
- [x] Understand how annotation data is accessed and structured
- [x] 2. Create the basic annotation list toolbox item
- [x] Create new file `src/toolbox_items/annotation_list.ts`
- [x] Implement basic UI structure (container, list elements)
- [x] Register the toolbox item in the main toolbox
- [x] 3. Implement core list functionality
- [x] Display all annotations with their ID/index
- [x] Add show/hide toggle for deprecated annotations (default: hide)
- [x] Add option to group by class
- [x] 4. Implement click-to-fly functionality
- [x] Integrate with existing "fly to" functionality from PR #230
- [x] Add click handlers to list items
- [x] Display "current idx / total" indicator
- [x] 5. Implement hover highlighting
- [x] Add hover handlers to list items
- [x] Integrate with existing annotation highlighting system
- [x] Ensure bidirectional highlighting (list hover → canvas, canvas hover → list)
37 changes: 37 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Publish to npm

on:
pull_request:
types:
- closed
branches:
- main
workflow_dispatch:

jobs:
publish:
# Only run if PR was merged (or manual dispatch)
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Publish to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ build
build/*
output.txt
test-results/
playwright-report/
playwright-report/
dist
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@

All notable changes to this project will be documented here.

## [unreleased]https://github.com/SenteraLLC/ulabel/pull/233
## [unreleased]

## [0.21.0] - Oct 27th, 2025
- Add toast notification that shows on `fly_to` calls and shows annotation position in the ordering (e.g., "3 / 10")
- Add `AnnotationList` toolbox item for managing and navigating annotations
- Displays all annotations in a scrollable list with spatial type icons and class names
- Bidirectional hover highlighting between list and canvas
- Filter options:
- Toggle show/hide deprecated annotations (default: hidden)
- Group annotations by class
- Collapsible interface to maximize toolbox space
- Add automated package deployment via GHA

## [0.20.0] - Oct 15th, 2025
- Add `fly-to` functions, which sets the zoom and focus to a specific annotation
Expand Down
26 changes: 25 additions & 1 deletion api_spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,8 @@ enum AllowedToolboxItem {
SubmitButtons, // 7
FilterDistance, // 8
Brush, // 9
ImageFilters // 10
ImageFilters, // 10
AnnotationList // 11
}
```
You can access the AllowedToolboxItem enum by calling the static method:
Expand Down Expand Up @@ -413,6 +414,29 @@ type ImageFiltersConfig = {

This toolbox item provides CSS filter controls that apply only to the image, not to the UI elements. Users can adjust brightness, contrast, hue rotation, inversion, and saturation using sliders. The filters are hardware-accelerated by modern browsers for optimal performance.

### `annotation_list_toolbox_item`

The `AnnotationList` toolbox item displays all annotations in the current subtask in a scrollable list. This toolbox item provides several features:

**Display Features:**
- Shows each annotation with its spatial type icon (bbox, polygon, point, etc.) and class name
- Displays annotation index (0-based) for easy reference
- Collapsible interface to maximize canvas space

**Filtering Options:**
- **Show Deprecated**: Toggle to show/hide deprecated annotations (default: hidden)
- **Group by Class**: Organize annotations by their classification for easier management

**Navigation:**
- Click any annotation in the list to fly-to and zoom on that annotation
- Toast notification appears showing current position (e.g., "3 / 10") when navigating

**Bidirectional Highlighting:**
- Hover over an annotation in the list to highlight it on the canvas with the ID dialog
- Hover over an annotation on the canvas to highlight its corresponding entry in the list

This toolbox item requires no configuration and can be added to the `toolbox_order` array using `AllowedToolboxItem.AnnotationList`.

### `change_zoom_keybind`
Keybind to change the zoom level. Must be a letter, and the lowercase version of the letter will set the zoom level to the `initial_crop`, while the capitalized version will show the full image. Default is `r`.

Expand Down
1 change: 1 addition & 0 deletions demo/multi-class.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
"toolbox_order": [
AllowedToolboxItem.SubmitButtons,
AllowedToolboxItem.ModeSelect,
AllowedToolboxItem.AnnotationList,
AllowedToolboxItem.ImageFilters,
AllowedToolboxItem.ZoomPan,
AllowedToolboxItem.AnnotationID,
Expand Down
61,536 changes: 0 additions & 61,536 deletions dist/ulabel.js

This file was deleted.

78 changes: 0 additions & 78 deletions dist/ulabel.js.LICENSE.txt

This file was deleted.

2 changes: 0 additions & 2 deletions dist/ulabel.min.js

This file was deleted.

78 changes: 0 additions & 78 deletions dist/ulabel.min.js.LICENSE.txt

This file was deleted.

2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = {
"node_modules/(?!(uuid)/)",
],
// Optimize memory usage
maxWorkers: 2,
maxWorkers: 4,
workerIdleMemoryLimit: "512MB",
// Clear cache between runs
clearMocks: true,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ulabel",
"description": "An image annotation tool.",
"version": "0.20.0",
"version": "0.21.0",
"main": "dist/ulabel.min.js",
"module": "dist/ulabel.min.js",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default defineConfig({
fullyParallel: false, // Run tests sequentially for more stable results
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: 2,
workers: 3,
reporter: "list",
use: {
baseURL: "http://localhost:8080",
Expand Down
1 change: 0 additions & 1 deletion pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
- [ ] Merged latest main
- [ ] Version number in `package.json` has been bumped since last release
- [ ] Version numbers match between package `package.json` and `src/version.js`
- [ ] Ran `npm install` and `npm run build` AFTER bumping the version number
- [ ] Updated documentation if necessary (currently just in `api_spec.md`)
- [ ] Added changes to `changelog.md`

Expand Down
Loading