Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
2ce3175
Create fonts.css
daniel-slaugh Aug 14, 2026
193c95b
Use fonts.css
daniel-slaugh Aug 14, 2026
8d31166
Enforce font compliance in CI
daniel-slaugh Aug 14, 2026
abcba7d
use <small> tag for secondary text
daniel-slaugh Aug 14, 2026
c801e59
Add font recipes
daniel-slaugh Aug 17, 2026
c56b235
Move tokens.css into design-system
daniel-slaugh Aug 17, 2026
83d20f1
Move non-global styles out of tokens.css
daniel-slaugh Aug 17, 2026
8a2fbbf
Add colors.ts and move Vuetify.ts into design-tokens
daniel-slaugh Aug 17, 2026
3d63875
Move everything color related into vuetify.ts
daniel-slaugh Aug 17, 2026
0f8d583
Update Workspaces.vue to use design-tokens
daniel-slaugh Aug 17, 2026
2a9bade
Update workspace page style
daniel-slaugh Aug 17, 2026
cfd271e
replace v-btn-add with primary
daniel-slaugh Aug 17, 2026
a6903fd
Remove role chip
daniel-slaugh Aug 17, 2026
a95474e
Make secondary action buttons grey
daniel-slaugh Aug 18, 2026
3b8cc1e
Style search bars and chip group
daniel-slaugh Aug 18, 2026
3b7fdc7
Swap in thick HydroServer logo
daniel-slaugh Aug 18, 2026
f77e25d
Add wave textures
daniel-slaugh Aug 18, 2026
2676d2f
Update workspace icons
daniel-slaugh Aug 18, 2026
886be5a
Polish Workspace styles
daniel-slaugh Aug 18, 2026
9089906
Remove waveform and restyle navbar active state
daniel-slaugh Aug 18, 2026
1c378f3
Clean up navbar
daniel-slaugh Aug 18, 2026
5c81c4b
Move help icons
daniel-slaugh Aug 18, 2026
5f11985
Remove newsreader font
daniel-slaugh Aug 18, 2026
e4b6728
Balance the margin on the account icon
daniel-slaugh Aug 19, 2026
327199c
Make input styles match
daniel-slaugh Aug 19, 2026
9b1d15d
Add GitHub-style collaborators table
daniel-slaugh Aug 19, 2026
34ad830
Add value coloring for collaborators search bar
daniel-slaugh Aug 19, 2026
18c33c5
Workspace filter bar to highlight on-focus
daniel-slaugh Aug 19, 2026
31d3eea
Restore HMR for external. vuetify.ts file
daniel-slaugh Aug 19, 2026
f050e68
Update search bar styles on table
daniel-slaugh Aug 19, 2026
310e9a0
Let tables shrink to fit content
daniel-slaugh Aug 19, 2026
508f25d
Make all of the workspace list area clickable
daniel-slaugh Aug 19, 2026
5a904bf
Fix collaborators not returning from API correctly
daniel-slaugh Aug 19, 2026
5a86691
Style 'add collaborator' form
daniel-slaugh Aug 19, 2026
88b78b8
Make table action icons consistent
daniel-slaugh Aug 20, 2026
8fa2212
Fix clipping on search bar
daniel-slaugh Aug 20, 2026
254f9ce
Update Service account table to work like collaborator table
daniel-slaugh Aug 20, 2026
23399c1
Make metadata table headers sticky
daniel-slaugh Aug 20, 2026
12934ee
Update permissions UI
daniel-slaugh Aug 20, 2026
2e1cd4e
Polish table loading state
daniel-slaugh Aug 20, 2026
f8983f7
Improve overview load time
daniel-slaugh Aug 20, 2026
e1a828c
Update job orchestration color styles
daniel-slaugh Aug 20, 2026
6f1ddfe
Update search bar style to conform to standard
daniel-slaugh Aug 20, 2026
9d81e03
Update ingestion view colors
daniel-slaugh Aug 20, 2026
69165b2
Move workspace selector
daniel-slaugh Aug 20, 2026
ca43e52
Make job orchestration ingestion tasks table key:value searchable
daniel-slaugh Aug 20, 2026
ecfc321
Make spacing consistent with workspace page
daniel-slaugh Aug 20, 2026
32de501
Remove ingestion table artifacts
daniel-slaugh Aug 20, 2026
7bbeed3
Add status filtering
daniel-slaugh Aug 20, 2026
4019650
Remove vuetify table artifacts
daniel-slaugh Aug 20, 2026
fb714e6
Fix table scrolling
daniel-slaugh Aug 20, 2026
c1dfc5e
Update CI to not trigger on push for feature branches
daniel-slaugh Aug 20, 2026
e6984b6
Move Workspace styles into design system
daniel-slaugh Aug 20, 2026
b88f109
Apply design system to job orchestration page
daniel-slaugh Aug 24, 2026
d69e015
Apply design system to products and quality tasks
daniel-slaugh Aug 24, 2026
0e6db7f
Update filter & search style of quality and products tables
daniel-slaugh Aug 24, 2026
1bfe8bc
Revert style of popup menu
daniel-slaugh Aug 24, 2026
257cf27
Fix cursor getting offset on search bars
daniel-slaugh Aug 24, 2026
6899e10
Fix job orchestration routing race condition
daniel-slaugh Aug 24, 2026
41067f3
Make all task names route to the details view
daniel-slaugh Aug 24, 2026
479d8d6
design system icon & button styles to job orchestration
daniel-slaugh Aug 24, 2026
97304dd
Apple design system to Visualize data page
daniel-slaugh Aug 24, 2026
cea320d
Make datastream selection clearable
daniel-slaugh Aug 24, 2026
22ddbf6
Update data visualization presentation
daniel-slaugh Aug 24, 2026
e284ce9
Move buttons with select context into select header
daniel-slaugh Aug 24, 2026
df3e706
Cap table height to num items
daniel-slaugh Aug 24, 2026
2bea718
Replace Copy State as URL with URL context
daniel-slaugh Aug 24, 2026
362191a
Update filter names
daniel-slaugh Aug 24, 2026
fd851aa
Context aware site labels
daniel-slaugh Aug 25, 2026
28419d5
Add detail levels
daniel-slaugh Aug 25, 2026
883ea00
Improve search functionality
daniel-slaugh Aug 25, 2026
fcbf68c
Add sorting functionality
daniel-slaugh Aug 25, 2026
edaf41f
Rename design-tokens to design-system
daniel-slaugh Aug 25, 2026
bd763a5
Move reusable components to design-system
daniel-slaugh Aug 25, 2026
d38ce0e
Remove dead code
daniel-slaugh Aug 25, 2026
78d94f7
Add agent instructions for frontend conventions
daniel-slaugh Aug 25, 2026
dd782c6
Update workspaces.vue components to conform to CONVENTIONS.md
daniel-slaugh Aug 25, 2026
b05932c
Browse page to conform to frontend conventions
daniel-slaugh Aug 25, 2026
d036c37
Apply design system to Django forms
daniel-slaugh Aug 26, 2026
4251469
Remove redundant color aliases
daniel-slaugh Aug 26, 2026
9739f74
Move vuetify design system files into vue dir
daniel-slaugh Aug 26, 2026
cee0aa9
Add role-based vuetify defaults
daniel-slaugh Aug 26, 2026
2fbd8be
Remove Tailwind from Django; Style datasteam @ monitoringSite
daniel-slaugh Aug 28, 2026
d4f1577
Update login styles
daniel-slaugh Aug 28, 2026
7a8e957
Tweak Login presentation
daniel-slaugh Aug 28, 2026
65ce503
Hide organization fields by default
daniel-slaugh Aug 28, 2026
598fb0a
UI rearranging on auth forms
daniel-slaugh Aug 28, 2026
2bb39b6
Make form fields look like Data Management App
daniel-slaugh Aug 28, 2026
05e0f44
Style submit buttons
daniel-slaugh Aug 28, 2026
5363a09
Fix signup form field spacing
daniel-slaugh Aug 31, 2026
24fb504
Merge branch 'release/v2.0.0' into 511-design-system
daniel-slaugh Aug 31, 2026
eca4780
Revert QC style to release/2.0.0
daniel-slaugh Aug 31, 2026
3aaf2ac
Update e2e tests
daniel-slaugh Aug 31, 2026
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
11 changes: 11 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "data-management",
"runtimeExecutable": "npm",
"runtimeArgs": ["--prefix", "apps/data-management", "run", "dev", "--", "--port", "5190", "--strictPort"],
"port": 5190
}
]
}
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ name: CI
on:
push:
branches:
- "**"
- main
pull_request:
release:
types: [created]

permissions:
contents: read
Expand Down
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
{
"label": "Start Backend",
"type": "shell",
"command": "${workspaceFolder}/scripts/dev-api-command manage.py tailwind runserver 0.0.0.0:8000",
"command": "${workspaceFolder}/scripts/dev-api-command manage.py runserver 0.0.0.0:8000",
"options": {
"cwd": "${workspaceFolder}/django"
},
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Frontend Changes

For frontend changes, conform to the conventions established in
[packages/design-system/CONVENTIONS.md](packages/design-system/CONVENTIONS.md).
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See [AGENTS.md](AGENTS.md) — the single source of truth for agent instructions in this repo.
12 changes: 6 additions & 6 deletions apps/data-management/e2e/specs/account.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ test.describe('account management', () => {

await page.getByTestId('account-menu-button').click()
await page.getByTestId('account-menu-item').click()
await expect(page).toHaveURL(/\/accounts\/profile\/$/)
await expect(page).toHaveURL(/\/accounts\/profile\/(?:\?.*)?$/)
await expect(page.getByRole('heading', { name: 'Profile' })).toBeVisible()
await expect(page.getByRole('heading', { name: 'Organization' })).toBeVisible()

await page.getByRole('link', { name: 'Edit' }).click()
await page.getByLabel('First name').fill('Profile Updated')
await page.getByRole('checkbox', { name: 'Organization Affiliation' }).uncheck()
await page.getByRole('button', { name: 'Save Changes' }).click()
await page.getByRole('checkbox', { name: 'Organization affiliation' }).uncheck()
await page.getByRole('button', { name: 'Save changes' }).click()

await expect(page.getByText('Profile Updated Example')).toBeVisible()
await expect(page.getByRole('heading', { name: 'Organization' })).toHaveCount(0)
Expand All @@ -50,14 +50,14 @@ test.describe('account management', () => {
await page.getByLabel('Type "delete my account and data" to confirm').fill(
'delete my account and data'
)
await page.getByRole('button', { name: 'Delete My Account' }).click()
await page.getByRole('button', { name: 'Delete my account' }).click()

await expect(page).toHaveURL(/\/accounts\/login\/$/)
await expect(page).toHaveURL(/\/accounts\/login\/(?:\?.*)?$/)

await page.getByLabel('Email').fill(users.deleteMe.email)
await page.getByLabel('Password').fill(users.deleteMe.password)
await page.getByRole('button', { name: 'Sign In' }).click()
await expect(page).toHaveURL(/\/accounts\/login\/$/)
await expect(page).toHaveURL(/\/accounts\/login\/(?:\?.*)?$/)
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible()
})
})
107 changes: 53 additions & 54 deletions apps/data-management/e2e/specs/metadata.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { expect, test } from '../support/test'
import { expect, test, type Page } from '../support/test'

import { authenticateSession } from '../support/auth'
import { fixtures, users } from '../support/fixtures'
import { fillCombobox, workspaceListItem } from '../support/ui'

async function selectMetadataScope(
page: Page,
scope: 'all' | 'workspace' | 'system'
) {
await page.getByTestId(`metadata-scope-${scope}`).click()
const table = page.getByTestId(`${scope}-metadata-table`)
await expect(table).toBeVisible()
return table
}

test.describe('metadata management', () => {
test('the metadata route redirects to the workspaces page metadata tab', async ({
page,
Expand All @@ -13,11 +23,11 @@ test.describe('metadata management', () => {

await expect(page).toHaveURL(/\/workspaces\?section=metadata/)
await expect(
page.getByRole('heading', { name: 'Manage workspaces' })
page.getByRole('heading', { name: fixtures.workspaces.private.name })
).toBeVisible()

// Workspace metadata is shown by default, with its own type tabs.
await expect(page.getByTestId('workspace-metadata-table')).toBeVisible()
// All metadata is shown by default, with its own type tabs.
await expect(page.getByTestId('all-metadata-table')).toBeVisible()
await expect(page.getByRole('tab', { name: 'Methods' })).toBeVisible()
await expect(
page.getByRole('tab', { name: 'Observed properties' })
Expand All @@ -32,11 +42,8 @@ test.describe('metadata management', () => {
await expect(page.getByTestId('system-metadata-table')).toHaveCount(0)

// Switching scope swaps to the system-scoped table.
await page
.getByRole('button', { name: 'System metadata', exact: true })
.click()
await expect(page.getByTestId('system-metadata-table')).toBeVisible()
await expect(page.getByTestId('workspace-metadata-table')).toHaveCount(0)
await selectMetadataScope(page, 'system')
await expect(page.getByTestId('all-metadata-table')).toHaveCount(0)
})

test('switching metadata scope shows workspace or system entries, not both at once', async ({
Expand All @@ -47,8 +54,7 @@ test.describe('metadata management', () => {
await workspaceListItem(page, fixtures.workspaces.private.name).click()

await page.getByRole('tab', { name: 'Methods' }).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await expect(
workspaceTable
.locator('tr')
Expand All @@ -57,11 +63,7 @@ test.describe('metadata management', () => {
).toBeVisible()
await expect(page.getByTestId('system-metadata-table')).toHaveCount(0)

await page
.getByRole('button', { name: 'System metadata', exact: true })
.click()

const systemTable = page.getByTestId('system-metadata-table')
const systemTable = await selectMetadataScope(page, 'system')
await expect(
systemTable
.locator('tr')
Expand All @@ -82,10 +84,9 @@ test.describe('metadata management', () => {
`/workspaces?workspace=${fixtures.workspaces.admin.id}&section=metadata`
)

await page.getByRole('button', { name: 'All', exact: true }).click()
const allTable = await selectMetadataScope(page, 'all')
await page.getByRole('tab', { name: 'Result qualifiers' }).click()

const allTable = page.getByTestId('all-metadata-table')
await allTable
.getByRole('textbox', { name: 'Search metadata' })
.fill(qualifier.name)
Expand All @@ -95,7 +96,7 @@ test.describe('metadata management', () => {
await expect(deleteButton).toBeVisible()

await editButton.click()
await page.getByLabel('Code *').fill(renamedCode)
await page.getByLabel('Code').fill(renamedCode)
await page.getByRole('button', { name: 'Update', exact: true }).click()

const renamedRow = allTable.locator('tr').filter({ hasText: renamedCode })
Expand All @@ -117,24 +118,24 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.private.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await page.getByRole('tab', { name: 'Methods' }).click()
await workspaceTable
.getByRole('button', { name: /Add new method/i })
.click()

await fillCombobox(page, 'Type *', 'E2E Method Type')
await fillCombobox(page, 'Type', 'E2E Method Type')
await page
.getByLabel('Description *')
.getByLabel('Description')
.fill('Temporary method created by the Playwright metadata CRUD suite.')
await page.getByLabel('Name *').fill(methodName)
await page.getByLabel('Name').fill(methodName)
await page.getByRole('button', { name: 'Save' }).click()

const methodRow = page.locator('tr').filter({ hasText: methodName }).first()
await expect(methodRow).toBeVisible()

await methodRow.locator('.v-icon').first().click()
await page.getByLabel('Name *').fill(renamedMethodName)
await page.getByLabel('Name').fill(renamedMethodName)
await page.getByRole('button', { name: 'Update' }).click()

const renamedMethodRow = page
Expand Down Expand Up @@ -165,21 +166,21 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.private.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await page.getByRole('tab', { name: 'Methods' }).click()
await workspaceTable
.getByRole('button', { name: /Add new method/i })
.click()

await fillCombobox(page, 'Type *', 'Instrument Deployment')
await fillCombobox(page, 'Type', 'Instrument Deployment')
await page
.getByLabel('Description *')
.getByLabel('Description')
.fill('Instrument method created by the Playwright regression suite.')

await expect(page.getByLabel('Name *', { exact: true })).toHaveCount(0)
await expect(page.getByLabel('Name', { exact: true })).toHaveCount(0)

const manufacturerField = page.getByLabel('Sensor Model Manufacturer *')
const modelField = page.getByLabel('Sensor Model *', { exact: true })
const manufacturerField = page.getByLabel('Sensor Model Manufacturer')
const modelField = page.getByLabel('Sensor Model', { exact: true })
await page.getByRole('button', { name: 'Save' }).click()
await expect(page.getByText('This field is required.')).toHaveCount(2)

Expand Down Expand Up @@ -210,30 +211,30 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.private.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await page.getByRole('tab', { name: 'Observed properties' }).click()
await workspaceTable
.getByRole('button', { name: /Add new observed property/i })
.click()

await fillCombobox(page, 'Variable Type *', 'E2E Variable Type')
await fillCombobox(page, 'Variable Type', 'E2E Variable Type')
await page
.getByLabel('Definition')
.fill('https://www.example.com/e2e-observed-property')
await page
.getByLabel('Description *')
.getByLabel('Description')
.fill(
'Temporary observed property created by the Playwright metadata CRUD suite.'
)
await page.getByLabel('Variable Code *').fill(`E2E-OP-${Date.now()}`)
await page.getByLabel('Name *').fill(propName)
await page.getByLabel('Variable Code').fill(`E2E-OP-${Date.now()}`)
await page.getByLabel('Name').fill(propName)
await page.getByRole('button', { name: 'Save' }).click()

const propRow = page.locator('tr').filter({ hasText: propName }).first()
await expect(propRow).toBeVisible()

await propRow.locator('.v-icon').first().click()
await page.getByLabel('Name *').fill(renamedPropName)
await page.getByLabel('Name').fill(renamedPropName)
await page.getByRole('button', { name: 'Update' }).click()

const renamedPropRow = page
Expand Down Expand Up @@ -262,16 +263,16 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.private.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await page.getByRole('tab', { name: 'Processing levels' }).click()
await workspaceTable
.getByRole('button', { name: /Add new processing level/i })
.click()

await page.getByLabel('Name *').fill('E2E Processing Level')
await page.getByLabel('Code *').fill(levelCode)
await page.getByLabel('Name').fill('E2E Processing Level')
await page.getByLabel('Code').fill(levelCode)
await page
.getByLabel('Description *')
.getByLabel('Description')
.fill('E2E processing level description')
await page
.getByLabel('Definition')
Expand All @@ -282,7 +283,7 @@ test.describe('metadata management', () => {
await expect(levelRow).toBeVisible()

await levelRow.locator('.v-icon').first().click()
await page.getByLabel('Code *').fill(renamedCode)
await page.getByLabel('Code').fill(renamedCode)
await page.getByRole('button', { name: 'Update' }).click()

const renamedRow = page
Expand Down Expand Up @@ -311,23 +312,23 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.private.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await page.getByRole('tab', { name: 'Units' }).click()
await workspaceTable.getByRole('button', { name: /Add new unit/i }).click()

await fillCombobox(page, 'Unit Type *', 'E2E Unit Type')
await page.getByLabel('Symbol *').fill(`e2e${stamp}`)
await fillCombobox(page, 'Unit Type', 'E2E Unit Type')
await page.getByLabel('Symbol').fill(`e2e${stamp}`)
await page
.getByLabel('Definition')
.fill(`https://example.com/units/e2e-${stamp}`)
await page.getByLabel('Name *').fill(unitName)
await page.getByLabel('Name').fill(unitName)
await page.getByRole('button', { name: 'Save' }).click()

const unitRow = page.locator('tr').filter({ hasText: unitName }).first()
await expect(unitRow).toBeVisible()

await unitRow.locator('.v-icon').first().click()
await page.getByLabel('Name *').fill(renamedUnitName)
await page.getByLabel('Name').fill(renamedUnitName)
await page.getByRole('button', { name: 'Update' }).click()

const renamedUnitRow = page
Expand Down Expand Up @@ -356,13 +357,13 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.private.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await page.getByRole('tab', { name: 'Result qualifiers' }).click()
await workspaceTable
.getByRole('button', { name: /Add new result qualifier/i })
.click()

await page.getByLabel('Code *').fill(qualifierCode)
await page.getByLabel('Code').fill(qualifierCode)
await page
.getByLabel('Description')
.fill(
Expand All @@ -377,7 +378,7 @@ test.describe('metadata management', () => {
await expect(qualifierRow).toBeVisible()

await qualifierRow.locator('.v-icon').first().click()
await page.getByLabel('Code *').fill(renamedCode)
await page.getByLabel('Code').fill(renamedCode)
await page.getByRole('button', { name: 'Update' }).click()

const renamedRow = page
Expand All @@ -400,11 +401,9 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.public.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')

const searchBox = page
.getByRole('textbox', { name: 'Search metadata', exact: true })
.first()
const searchBox = workspaceTable.getByPlaceholder('Search metadata…')
await expect(searchBox).toBeVisible()

await searchBox.fill(fixtures.metadata.publicAssignedMethod.name)
Expand Down Expand Up @@ -432,7 +431,7 @@ test.describe('metadata management', () => {
await page.goto('/metadata')
await workspaceListItem(page, fixtures.workspaces.private.name).click()

const workspaceTable = page.getByTestId('workspace-metadata-table')
const workspaceTable = await selectMetadataScope(page, 'workspace')
await page.getByRole('tab', { name: 'Methods' }).click()

const assignedMethodRow = workspaceTable
Expand Down
Loading
Loading