diff --git a/assets/assetpack.def b/assets/assetpack.def
index 66bbda5a..551cc07e 100644
--- a/assets/assetpack.def
+++ b/assets/assetpack.def
@@ -122,6 +122,7 @@
< javascripts/admin_user.js
< javascripts/audit_log.js
< javascripts/server.js
+< javascripts/project.js
< https://raw.githubusercontent.com/bootstrapthemesco/bootstrap-4-multi-dropdown-navbar/beta2.0/js/bootstrap-4-navbar.js
< https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.js
< https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.js
diff --git a/assets/javascripts/admintable.js b/assets/javascripts/admintable.js
index 2fc05b22..a9e720de 100644
--- a/assets/javascripts/admintable.js
+++ b/assets/javascripts/admintable.js
@@ -291,6 +291,17 @@ function renderAdminTableHostname(data, type, row, meta) {
return data? '' + htmlEscape(data) + '>' : '';
}
+function renderAdminTableProjectName(data, type, row, meta) {
+ if (type !== 'display') {
+ return data ? data : '';
+ }
+ if (isEditingAdminTableRow(meta)) {
+ return '';
+ }
+ return data? '' + htmlEscape(data) + '>' : '';
+}
+
+
function renderAdminTableLongText(data, type, row, meta) {
if (type !== 'display') {
return data ? data : '';
@@ -382,6 +393,8 @@ function setupAdminTable(editable) {
var emptyRow = {};
var columns = [];
var columnDefs = [];
+ var url = $("#admintable_api_url").val() + window.location.search;
+
var thElements = $('.admintable thead th').each(function() {
var th = $(this);
@@ -403,6 +416,8 @@ function setupAdminTable(editable) {
if (th.hasClass('col_value')) {
if (columnName == 'hostname') {
columnDef.render = renderAdminTableHostname;
+ } else if (columnName == 'name' && url && url.startsWith('/rest/project')) {
+ columnDef.render = renderAdminTableProjectName;
} else if (columnName == 'public notes' || columnName == 'comment' || columnName == 'sponsor') {
columnDef.render = renderAdminTableLongText;
} else {
@@ -429,7 +444,6 @@ function setupAdminTable(editable) {
});
// setup admin table
- var url = $("#admintable_api_url").val() + window.location.search;
var table = $('.admintable');
var dataTable = table.DataTable({
order: [
diff --git a/assets/javascripts/project.js b/assets/javascripts/project.js
new file mode 100644
index 00000000..2fcd9efe
--- /dev/null
+++ b/assets/javascripts/project.js
@@ -0,0 +1,11 @@
+function setupProjectPropagation(id) {
+ var table = $('#project_propagation');
+ var dataTable = table.DataTable({
+ ajax: {
+ url: '/rest/project/propagation/' + id,
+ },
+ deferRender: true,
+ columns: [{data: 'dt'}, {data: 'prefix'}, {data: 'version'}, {data: 'mirrors'}],
+ order: [[0, 'desc']],
+ });
+}
diff --git a/lib/MirrorCache/Schema/Result/Project.pm b/lib/MirrorCache/Schema/Result/Project.pm
index a7e57229..8ca2a503 100644
--- a/lib/MirrorCache/Schema/Result/Project.pm
+++ b/lib/MirrorCache/Schema/Result/Project.pm
@@ -36,4 +36,6 @@ __PACKAGE__->add_columns(
db_sync_full_every => { data_type => "integer", is_nullable => 1 },
);
+
+__PACKAGE__->set_primary_key("id");
1;
diff --git a/lib/MirrorCache/Schema/ResultSet/Rollout.pm b/lib/MirrorCache/Schema/ResultSet/Rollout.pm
index b8a274f9..cbfb1c0d 100644
--- a/lib/MirrorCache/Schema/ResultSet/Rollout.pm
+++ b/lib/MirrorCache/Schema/ResultSet/Rollout.pm
@@ -83,6 +83,13 @@ sub add_rollout_server {
my $dbh = $self->result_source->schema->storage->dbh;
my $sql = 'insert into rollout_server(rollout_id, server_id, dt) select ?, ?, now()';
+
+ if ($dbh->{Driver}->{Name} eq 'Pg') {
+ $sql = $sql . ' on conflict do nothing';
+ } else {
+ $sql = $sql . ' on duplicate key update server_id = server_id';
+ }
+
$dbh->prepare($sql)->execute($rollout_id, $server_id);
return 1;
}
diff --git a/lib/MirrorCache/WebAPI.pm b/lib/MirrorCache/WebAPI.pm
index 57ae47c4..c82f6a22 100644
--- a/lib/MirrorCache/WebAPI.pm
+++ b/lib/MirrorCache/WebAPI.pm
@@ -178,10 +178,12 @@ sub _setup_webui {
$rest_r->get('/server/location') ->to('server_location#list');
$rest_r->get('/server/:id')->to('table#list', table => 'Server');
$rest_r->get('/server/check/:id')->name('rest_get_server_check')->to('server_note#list_incident');
- $rest_r->get('/project')->to('project#list');
- $rest_r->get('/project/:name')->to('project#show');
+ $rest_r->get('/project')->name('rest_project')->to('table#list', table => 'Project');
+ # $rest_r->get('/project/:name')->to('project#show');
+ $rest_r->get('/project/:id')->to('table#list', table => 'Project');
$rest_r->get('/project/:name/mirror_summary')->to('project#mirror_summary');
$rest_r->get('/project/:name/mirror_list')->to('project#mirror_list');
+ $rest_r->get('/project/propagation/:project_id')->to('project_propagation#list');
my $rest_operator_auth;
$rest_operator_auth = $rest->under('/')->to('session#ensure_operator');
@@ -196,6 +198,10 @@ sub _setup_webui {
$rest_operator_r->get('/server/contact/#hostname')->name('rest_get_server_contact')->to('server_note#list_contact');
$rest_operator_r->post('/sync_tree')->name('rest_post_sync_tree')->to('folder_jobs#sync_tree');
+ $rest_operator_r->post('/project')->to('table#create', table => 'Project');
+ $rest_operator_r->post('/project/:id')->name('post_project')->to('table#update', table => 'Project');
+ $rest_operator_r->delete('/project/:id')->to('table#destroy', table => 'Project');
+
$rest_r->get('/myserver')->name('rest_myserver')->to('table#list', table => 'MyServer');
$rest_r->get('/myserver/:id')->to('table#list', table => 'MyServer');
my $rest_usr_auth;
@@ -229,6 +235,8 @@ sub _setup_webui {
$app_r->get('/myserver')->name('myserver')->to('myserver#index');
$app_r->get('/folder')->name('folder')->to('folder#index');
$app_r->get('/folder/<%= title %>
+
+ %= include 'layouts/info'
+
+
+
+
+ % if (is_admin && !eval('$mirror_provider_url')) {
+
+
+
+
+
+ Id
+ Name
+ Path
+ Actions
+ Project: <%= $project->{name} %>
+
+ Propagation on Mirrors
+
+
+
+
+Time
+ Prefix
+ Version
+ Mirrors
+
+