diff --git a/alembic/versions/migrate_download_channel_to_collection.py b/alembic/versions/migrate_download_channel_to_collection.py
index 5e328232..8b5be1a8 100644
--- a/alembic/versions/migrate_download_channel_to_collection.py
+++ b/alembic/versions/migrate_download_channel_to_collection.py
@@ -71,6 +71,45 @@ def upgrade():
op.drop_column('download', 'channel_id')
print("Done\n")
+ # Step 6: Fix the update_channel_minimum_frequency trigger function
+ # It was referencing channel_id which no longer exists
+ print("Step 6: Updating update_channel_minimum_frequency trigger function...")
+ op.execute("""
+ CREATE OR REPLACE FUNCTION update_channel_minimum_frequency()
+ RETURNS TRIGGER AS
+ $$
+ DECLARE
+ v_channel_id INTEGER;
+ BEGIN
+ -- Handle INSERT and UPDATE: use NEW record
+ IF (TG_OP = 'DELETE') THEN
+ -- For DELETE, we need to find the channel from OLD record
+ IF OLD.collection_id IS NOT NULL THEN
+ SELECT id INTO v_channel_id FROM channel WHERE collection_id = OLD.collection_id;
+ IF v_channel_id IS NOT NULL THEN
+ UPDATE channel
+ SET minimum_frequency = (SELECT MIN(frequency) FROM download WHERE collection_id = OLD.collection_id)
+ WHERE id = v_channel_id;
+ END IF;
+ END IF;
+ RETURN OLD;
+ ELSE
+ -- For INSERT and UPDATE, use NEW record
+ IF NEW.collection_id IS NOT NULL THEN
+ SELECT id INTO v_channel_id FROM channel WHERE collection_id = NEW.collection_id;
+ IF v_channel_id IS NOT NULL THEN
+ UPDATE channel
+ SET minimum_frequency = (SELECT MIN(frequency) FROM download WHERE collection_id = NEW.collection_id)
+ WHERE id = v_channel_id;
+ END IF;
+ END IF;
+ RETURN NEW;
+ END IF;
+ END;
+ $$ LANGUAGE plpgsql;
+ """)
+ print("Done\n")
+
print("=" * 60)
print("Migration Complete")
print("=" * 60 + "\n")
@@ -83,6 +122,20 @@ def downgrade():
bind = op.get_bind()
session = Session(bind=bind)
+ # Restore the old trigger function that uses channel_id
+ op.execute("""
+ CREATE OR REPLACE FUNCTION update_channel_minimum_frequency()
+ RETURNS TRIGGER AS
+ $$
+ BEGIN
+ UPDATE channel
+ SET minimum_frequency = (SELECT MIN(frequency) FROM download WHERE channel_id = NEW.channel_id)
+ WHERE id = NEW.channel_id;
+ RETURN NEW;
+ END;
+ $$ LANGUAGE plpgsql;
+ """)
+
# Add back channel_id column
op.add_column('download', sa.Column('channel_id', sa.Integer(), nullable=True))
diff --git a/app/src/api.js b/app/src/api.js
index a29922e1..fd38689c 100644
--- a/app/src/api.js
+++ b/app/src/api.js
@@ -722,7 +722,7 @@ export async function fetchDomains() {
const response = await apiGet(`${COLLECTIONS_API}?kind=domain`);
if (response.ok) {
let data = await response.json();
- return [data['collections'], data['totals']['collections'], data['metadata']];
+ return [data['collections'], data['totals']['collections']];
} else {
const message = await getErrorMessage(response, 'Unable to fetch Domains. See server logs.');
toast({
@@ -738,7 +738,7 @@ export async function fetchChannels() {
const response = await apiGet(`${COLLECTIONS_API}?kind=channel`);
if (response.ok) {
let data = await response.json();
- return [data['collections'], data['totals']['collections'], data['metadata']];
+ return [data['collections'], data['totals']['collections']];
} else {
const message = await getErrorMessage(response, 'Unable to fetch Channels. See server logs.');
toast({
diff --git a/app/src/components/Archive.js b/app/src/components/Archive.js
index 6b25c825..1d10af19 100644
--- a/app/src/components/Archive.js
+++ b/app/src/components/Archive.js
@@ -38,7 +38,6 @@ import {Link, Route, Routes, useLocation, useNavigate, useParams} from "react-ro
import Message from "semantic-ui-react/dist/commonjs/collections/Message";
import {
useArchive,
- useCollectionMetadata,
useDomain,
useDomains,
useOneQuery,
@@ -356,10 +355,27 @@ export function ArchiveCard({file}) {
}
+// Domain table column configuration
+const DOMAIN_COLUMNS = [
+ {key: 'domain', label: 'Domain', sortable: true, width: 7},
+ {key: 'tag_name', label: 'Tag', sortable: true, width: 2},
+ {key: 'archive_count', label: 'Archives', sortable: true, align: 'right', width: 2},
+ {key: 'min_download_frequency', label: 'Download Frequency', sortable: true, format: 'frequency', width: 2, hideOnMobile: true},
+ {key: 'size', label: 'Size', sortable: true, align: 'right', format: 'bytes', width: 2, hideOnMobile: true},
+ {key: 'actions', label: 'Manage', sortable: false, type: 'actions', width: 1}
+];
+
+const DOMAIN_ROUTES = {
+ list: '/archive/domains',
+ edit: '/archive/domain/:id/edit',
+ search: '/archive',
+ searchParam: 'domain'
+};
+
export function DomainsPage() {
useTitle('Archive Domains');
- const [domains, total, metadata] = useDomains();
+ const [domains] = useDomains();
const [searchStr, setSearchStr] = useOneQuery('domain');
// Header section matching ChannelsPage pattern
@@ -406,30 +422,33 @@ export function DomainsPage() {
{header}