From: Vásáry Dániel Date: Mon, 20 Nov 2017 13:51:32 +0000 (+0000) Subject: git-tfs-id: [http://tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube... X-Git-Url: http://git.useribm.hu/?a=commitdiff_plain;h=7f9b945b8afd8c5ecf028de2fa4f04f8a08226b6;p=mediacube.git git-tfs-id: [tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube;C30749 --- diff --git a/client/Maestro/Configuration/configuration-editor.json b/client/Maestro/Configuration/configuration-editor.json index 98f3a22b..1ea79085 100644 --- a/client/Maestro/Configuration/configuration-editor.json +++ b/client/Maestro/Configuration/configuration-editor.json @@ -1,6 +1,6 @@ { "title": "Szerkesztő", - "active": true, + "active": false, "startInTray": false, "enableCustomMetadataId": true, "player": { @@ -42,22 +42,25 @@ ], "targets": [ { - "label": "Hír nyersanyag betöltés", + "label": "Stúdióba küldés", "processor": "FTPTargetProcessor", - "outputFormat": "%ID%-%SOURCENAME%", + "outputFormat": "%ID%", "tag": "Betöltés", - "subFolderFormat": "%IDROOT%", + "nexioServer": true, + "nexioFileExistsMessage": "A feltöltéshez új 'placeholder' generálása szükséges az Octopus rendszerben, az anyagon belül az ALT+1 billenytűkombináció segítségével.", "killDateDays": 7, - "saveArchiveMetadata": false, + "disableFileVersioning": true, + "agency": "MAESTRO-EDITOR", + "reference": [ "Octopus mappába küldés" ], "remote": { - "address": "ftp://10.10.1.100/OCTOPUS", - "userName": "mediacube", - "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "address": "ftp://10.10.1.55:2098", + "userName": "administrator", + "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh", "timeout": 1000 } }, { - "label": "Magazin nyersanyag betöltés", + "label": "Octopus mappába küldés", "processor": "FTPTargetProcessor", "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", @@ -65,27 +68,24 @@ "killDateDays": 7, "saveArchiveMetadata": false, "remote": { - "address": "ftp://10.10.1.100/PLAYOUT_NLE", + "address": "ftp://10.10.1.100/OCTOPUS", "userName": "mediacube", "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, { - "label": "Stúdióba küldés", + "label": "Traffic mappába küldés", "processor": "FTPTargetProcessor", - "outputFormat": "%ID%", + "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", - "nexioServer": true, - "nexioFileExistsMessage": "A feltöltéshez új 'placeholder' generálása szükséges az Octopus rendszerben, az anyagon belül az ALT+1 billenytűkombináció segítségével.", + "subFolderFormat": "%IDROOT%", "killDateDays": 7, - "disableFileVersioning": true, - "agency": "MAESTRO-EDITOR", - "reference": "Hír nyersanyag betöltés", + "saveArchiveMetadata": false, "remote": { - "address": "ftp://10.10.1.55:2098", - "userName": "administrator", - "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh", + "address": "ftp://10.10.1.100/PLAYOUT_NLE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, diff --git a/client/Maestro/Configuration/configuration-nexio-ingest.json b/client/Maestro/Configuration/configuration-nexio-ingest.json index 17c6143e..829e0542 100644 --- a/client/Maestro/Configuration/configuration-nexio-ingest.json +++ b/client/Maestro/Configuration/configuration-nexio-ingest.json @@ -12,7 +12,16 @@ "$type": "UNCSource", "filter": "avi,wav,mxf", "local": { - "address": "file://c:/x" + "address": "file://10.10.1.100/BRAAVOS/READY", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + }, + "remote": { + "address": "ftp://10.10.1.100/READY", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 } }, "metadatas": [ @@ -34,21 +43,79 @@ } ], "targets": [ + { + "label": "Octopus mappába küldés", + "processor": "FTPTargetProcessor", + "outputFormat": "%ID%-%SOURCENAME%", + "tag": "Betöltés", + "subFolderFormat": "%IDROOT%", + "killDateDays": 7, + "saveArchiveMetadata": false, + "remote": { + "address": "ftp://10.10.1.100/OCTOPUS", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + } + }, + { + "label": "Traffic mappába küldés", + "processor": "FTPTargetProcessor", + "outputFormat": "%ID%-%SOURCENAME%", + "tag": "Betöltés", + "subFolderFormat": "%IDROOT%", + "killDateDays": 7, + "saveArchiveMetadata": false, + "remote": { + "address": "ftp://10.10.1.100/PLAYOUT_NLE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + } + }, { "label": "Stúdióba küldés", "processor": "FTPTargetProcessor", "outputFormat": "%ID%", "tag": "Betöltés", "nexioServer": true, + "nexioFileExistsMessage": "A feltöltéshez új 'placeholder' generálása szükséges az Octopus rendszerben, az anyagon belül az ALT+1 billenytűkombináció segítségével.", "killDateDays": 7, "disableFileVersioning": true, - "agency": "HÍRADÓ TEST", + "agency": "MAESTRO-EDITOR", + "reference": [ "Octopus mappába küldés" ], "remote": { "address": "ftp://10.10.1.55:2098", "userName": "administrator", "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh", "timeout": 1000 } + }, + { + "label": "Lebonyba küldés", + "processor": "FTPTargetProcessor", + "outputFormat": "%ID%", + "tag": "Betöltés", + "killDateDays": 7, + "remote": { + "address": "ftp://10.10.1.100/PLAYOUT_CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + } + }, + { + "label": "Archiválás", + "processor": "FTPTargetProcessor", + "outputFormat": "%ID%", + "tag": "Archiválás", + "saveArchiveMetadata": true, + "remote": { + "address": "ftp://10.10.1.100/ARCHIVE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + } } ] } diff --git a/client/Maestro/Configuration/configuration-nle.json b/client/Maestro/Configuration/configuration-nle.json index 3ec60cf9..78e56c0c 100644 --- a/client/Maestro/Configuration/configuration-nle.json +++ b/client/Maestro/Configuration/configuration-nle.json @@ -1,6 +1,6 @@ { "title": "NLE", - "active": false, + "active": true, "startInTray": false, "enableCustomMetadataId": true, "player": { @@ -11,6 +11,7 @@ "source": { "$type": "UNCSource", "filter": "avi,wav,mxf", + "foldersAutoExpand": true, "local": { "address": "file://c:/x" } @@ -42,7 +43,25 @@ ], "targets": [ { - "label": "Hír nyersanyag betöltés", + "label": "Stúdióba küldés", + "processor": "FTPTargetProcessor", + "outputFormat": "%ID%", + "tag": "Betöltés", + "nexioServer": true, + "nexioFileExistsMessage": "A feltöltéshez új 'placeholder' generálása szükséges az Octopus rendszerben, az anyagon belül az ALT+1 billenytűkombináció segítségével.", + "killDateDays": 7, + "disableFileVersioning": true, + "agency": "MAESTRO-NLE", + "reference": [ "Octopus mappába küldés", "Megtekintőbe küldés" ], + "remote": { + "address": "ftp://10.10.1.55:2098", + "userName": "administrator", + "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh", + "timeout": 1000 + } + }, + { + "label": "Octopus mappába küldés", "processor": "FTPTargetProcessor", "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", @@ -57,7 +76,7 @@ } }, { - "label": "Magazin nyersanyag betöltés", + "label": "Megtekintőbe küldés", "processor": "FTPTargetProcessor", "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", @@ -65,25 +84,24 @@ "killDateDays": 7, "saveArchiveMetadata": false, "remote": { - "address": "ftp://10.10.1.100/PLAYOUT_NLE", + "address": "ftp://10.10.1.100/OCTOPUS", "userName": "mediacube", "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, { - "label": "Stúdióba küldés", + "label": "Traffic mappába küldés", "processor": "FTPTargetProcessor", - "outputFormat": "%ID%", + "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", - "nexioServer": true, + "subFolderFormat": "%IDROOT%", "killDateDays": 7, - "agency": "MAESTRO-NLE", - "reference": "Hír nyersanyag betöltés", + "saveArchiveMetadata": false, "remote": { - "address": "ftp://10.10.1.56:2098", - "userName": "administrator", - "password": "+QtkeQdCTiOvZOgK/kUND4pO4/D+//r7ZIyluwMMdiqMEgO8iJErAG10ooWhPfiljQeXrdeyMzo7gWEZtcWpNSomGeDIbdMyQwtpqmMo1VEM3A27ZfzigY09YD46ECRh", + "address": "ftp://10.10.1.100/PLAYOUT_NLE", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } }, diff --git a/client/Maestro/Configuration/configuration-playout-ingest.json b/client/Maestro/Configuration/configuration-playout-ingest.json index ddd13040..aa818ef7 100644 --- a/client/Maestro/Configuration/configuration-playout-ingest.json +++ b/client/Maestro/Configuration/configuration-playout-ingest.json @@ -1,6 +1,6 @@ { "title": "Lebony betöltő", - "active": false, + "active": true, "startInTray": false, "enableCustomMetadataId": true, "player": { diff --git a/client/Maestro/Configuration/configuration-playout.json b/client/Maestro/Configuration/configuration-playout.json index 6834ae47..cf4d62ed 100644 --- a/client/Maestro/Configuration/configuration-playout.json +++ b/client/Maestro/Configuration/configuration-playout.json @@ -55,7 +55,7 @@ "outputFormat": "%ID%", "saveSegments": true, "tag": "Adáskész", - "reference": "Archiválás", + "reference": [ "Archiválás" ], "remote": { "address": "ftp://10.10.1.100/PLAYOUT/IceGateway", "userName": "mediacube", diff --git a/client/Maestro/Configuration/configuration-studio.json b/client/Maestro/Configuration/configuration-studio.json index a3db7e94..a159bf7b 100644 --- a/client/Maestro/Configuration/configuration-studio.json +++ b/client/Maestro/Configuration/configuration-studio.json @@ -1,6 +1,6 @@ { "title": "Stúdió", - "active": false, + "active": true, "startInTray": false, "enableCustomMetadataId": true, "filter": "avi", diff --git a/client/Maestro/Configuration/configuration-sxs.json b/client/Maestro/Configuration/configuration-sxs.json index 67622e77..c8fcc10a 100644 --- a/client/Maestro/Configuration/configuration-sxs.json +++ b/client/Maestro/Configuration/configuration-sxs.json @@ -42,7 +42,7 @@ ], "targets": [ { - "label": "Hír nyersanyag betöltés", + "label": "Octopus mappába küldés", "processor": "FTPTargetProcessor", "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", @@ -57,7 +57,7 @@ } }, { - "label": "Magazin nyersanyag betöltés", + "label": "Traffic mappába küldés", "processor": "FTPTargetProcessor", "outputFormat": "%ID%-%SOURCENAME%", "tag": "Betöltés", diff --git a/client/Maestro/Resources/installforge-installer-project.ifp b/client/Maestro/Installer/installforge-installer-project.ifp similarity index 96% rename from client/Maestro/Resources/installforge-installer-project.ifp rename to client/Maestro/Installer/installforge-installer-project.ifp index 22a3b598..d44b6c2a 100644 Binary files a/client/Maestro/Resources/installforge-installer-project.ifp and b/client/Maestro/Installer/installforge-installer-project.ifp differ diff --git a/client/Maestro/Maestro.csproj b/client/Maestro/Maestro.csproj index 2d6834b4..d1554c33 100644 --- a/client/Maestro/Maestro.csproj +++ b/client/Maestro/Maestro.csproj @@ -326,7 +326,7 @@ - + diff --git a/client/Maestro/MaestroForm.Designer.cs b/client/Maestro/MaestroForm.Designer.cs index 69730c92..69214110 100644 --- a/client/Maestro/MaestroForm.Designer.cs +++ b/client/Maestro/MaestroForm.Designer.cs @@ -202,6 +202,7 @@ namespace Maestro { this.treeFolders.BorderStyle = System.Windows.Forms.BorderStyle.None; this.treeFolders.Dock = System.Windows.Forms.DockStyle.Bottom; this.treeFolders.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238))); + this.treeFolders.HotTracking = true; this.treeFolders.ImageIndex = 0; this.treeFolders.ImageList = this.ilFolders; this.treeFolders.Location = new System.Drawing.Point(10, 206); @@ -210,6 +211,8 @@ namespace Maestro { this.treeFolders.Size = new System.Drawing.Size(330, 161); this.treeFolders.TabIndex = 18; this.treeFolders.Visible = false; + this.treeFolders.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.OnBeforeExpandFolder); + this.treeFolders.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.OnAfterSelectFolder); // // ilFolders // @@ -300,6 +303,7 @@ namespace Maestro { // btnShowFolders // this.btnShowFolders.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.btnShowFolders.Enabled = false; this.btnShowFolders.Image = global::Maestro.Properties.Resources.ic_folder_open_black_24dp_1x; this.btnShowFolders.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.btnShowFolders.ImageTransparentColor = System.Drawing.Color.GreenYellow; diff --git a/client/Maestro/MaestroForm.Source.cs b/client/Maestro/MaestroForm.Source.cs index a13d6365..a11fbbb1 100644 --- a/client/Maestro/MaestroForm.Source.cs +++ b/client/Maestro/MaestroForm.Source.cs @@ -1,7 +1,6 @@ using DxPlay; using Maestro.Metadata; using Maestro.Sources; -using MaestroShared.Commons; using MaestroShared.Configuration; using MaestroShared.Metadata; using MaestroShared.Resources; @@ -11,6 +10,7 @@ using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; +using System.Text; using System.Windows.Forms; namespace Maestro { @@ -20,7 +20,7 @@ namespace Maestro { public partial class MaestroForm { private ISource source; private SourceInfo selectedSource; - private List selectedSourceRows = new List(); + private List selectedSourceItems = new List(); public SourceInfo SelectedSource { get { @@ -29,7 +29,7 @@ namespace Maestro { set { selectedSource = value; if (selectedSource == null) - selectedSourceRows.Clear(); + selectedSourceItems.Clear(); textSelectedSource.Text = selectedSource?.Name; archiveMetadata = null; segments = null; @@ -45,8 +45,8 @@ namespace Maestro { Uri localAddress = Configuration?.Source?.Local?.Address; Uri remoteAddress = Configuration?.Source?.Remote?.Address; if (String.IsNullOrEmpty(remoteAddress?.ToString())) { - if (!String.IsNullOrEmpty(localAddress?.ToString())) - formTooltip.SetToolTip(groupSource, localAddress?.ToString()); + if (!String.IsNullOrEmpty(localAddress?.LocalPath)) + formTooltip.SetToolTip(groupSource, localAddress.LocalPath); } else formTooltip.SetToolTip(groupSource, remoteAddress?.ToString()); @@ -88,9 +88,9 @@ namespace Maestro { foreach (var folder in folders) { TreeNode folderNode = rootNode.Nodes.Add(GetLastSegment(folder)); folderNode.Nodes.Add(".."); - folderNode.ImageIndex = 0; - } + if ((Configuration.Source as UNCSource).FoldersAutoExpand) + treeFolders.ExpandAll(); } private void HideFolders() { @@ -99,6 +99,47 @@ namespace Maestro { treeFolders.Nodes.Clear(); } + private string GetPath(TreeNode node) { + TreeNode treeNode = node; + StringBuilder sb = new StringBuilder(); + sb.Append(treeNode.Text); + while (treeNode.Level != 1) { + treeNode = treeNode.Parent; + sb.Insert(0, "/"); + sb.Insert(0, treeNode.Text); + } + return sb.ToString(); + } + + private void OnBeforeExpandFolder(object sender, TreeViewCancelEventArgs e) { + if (e.Node.Nodes.Count != 1 || !"..".Equals(e.Node.Nodes[0].Text)) + return; + e.Node.Nodes.Clear(); + Uri address = new Uri(Path.Combine(Configuration.Source.Local.Address.LocalPath, GetPath(e.Node))); + string[] folders = Directory.GetDirectories(address.LocalPath); + foreach (var folder in folders) { + TreeNode folderNode = e.Node.Nodes.Add(GetLastSegment(folder)); + folderNode.Nodes.Add(".."); + } + } + + private void OnAfterSelectFolder(object sender, TreeViewEventArgs e) { + if (e.Action != TreeViewAction.ByMouse) + return; + txtSourceFilter.Text = null; + FileSystemSource source = bindingSource.DataSource as FileSystemSource; + Uri address = null; + if (e.Node.Level == 0) + address = Configuration.Source.Local.Address; + else + address = new Uri(Path.Combine(Configuration.Source.Local.Address.LocalPath, GetPath(e.Node))); + if (!String.IsNullOrEmpty(address.LocalPath)) + formTooltip.SetToolTip(groupSource, address.LocalPath); + source.Reset(address.LocalPath); + btnShowFolders.Checked = false; + HideFolders(); + } + private void OnShowFolders(object sender, EventArgs e) { if (btnShowFolders.CheckState == CheckState.Checked) { HideFolders(); @@ -135,7 +176,6 @@ namespace Maestro { if (selectedrows == null) return; if (e.ColumnIndex == 0) { - UpdateCheckStates(selectedrows); return; } @@ -166,37 +206,63 @@ namespace Maestro { } private void UpdateCheckStates(DataGridViewSelectedRowCollection selectedRows) { - IEnumerable currentSelectedRows = selectedRows.Cast(); - if (currentSelectedRows == null) + IEnumerable currentSelectedItems = selectedRows.Cast().Select(r => r.DataBoundItem as ISourceItem); + if (currentSelectedItems == null) return; - int checkedCount = currentSelectedRows.Count(r => AsISourceItem(r).IsChecked); - foreach (DataGridViewRow row in selectedRows) { - ISourceItem item = AsISourceItem(row); + int checkedCount = currentSelectedItems.Count(r => r.IsChecked); + foreach (ISourceItem item in currentSelectedItems) { if (selectedRows.Count == 1) item.IsChecked = !item.IsChecked; else item.IsChecked = checkedCount == selectedRows.Count ? false : true; if (item.IsChecked) { - if (!selectedSourceRows.Contains(row)) { - selectedSourceRows.Add(row); - Debug.WriteLine("Added " + AsISourceItem(row).Name); + if (!selectedSourceItems.Contains(item)) { + selectedSourceItems.Add(item); + Debug.WriteLine("Added " + item.Name); } } else { - if (selectedSourceRows.Contains(row)) { - selectedSourceRows.Remove(row); - Debug.WriteLine("Removed " + AsISourceItem(row).Name); + if (selectedSourceItems.Contains(item)) { + selectedSourceItems.Remove(item); + Debug.WriteLine("Removed " + item.Name); } } } SetSelectedSource(); } + //private void UpdateCheckStates_(DataGridViewSelectedRowCollection selectedRows) { + // IEnumerable currentSelectedRows = selectedRows.Cast(); + // if (currentSelectedRows == null) + // return; + // int checkedCount = currentSelectedRows.Count(r => AsISourceItem(r).IsChecked); + // foreach (DataGridViewRow row in selectedRows) { + // ISourceItem item = AsISourceItem(row); + // if (selectedRows.Count == 1) + // item.IsChecked = !item.IsChecked; + // else + // item.IsChecked = checkedCount == selectedRows.Count ? false : true; + + // if (item.IsChecked) { + // if (!selectedSourceRows.Contains(row)) { + // selectedSourceRows.Add(row); + // Debug.WriteLine("Added " + AsISourceItem(row).Name); + // } + // } else { + // if (selectedSourceRows.Contains(row)) { + // selectedSourceRows.Remove(row); + // Debug.WriteLine("Removed " + AsISourceItem(row).Name); + // } + // } + // } + // SetSelectedSource(); + //} + private void SetSelectedSource() { string selectionPrefix = null; string selectedNames = String.Empty; - foreach (DataGridViewRow actual in selectedSourceRows) { - string name = (actual.DataBoundItem as ISourceItem)?.Name; + foreach (ISourceItem actual in selectedSourceItems) { + string name = actual.Name; if (String.IsNullOrEmpty(name)) continue; selectedNames += name + " "; @@ -226,9 +292,9 @@ namespace Maestro { private FileInfo GetSelectedSourceFileInfo() { if (Configuration.Source.GetType() == typeof(NEXIOSource)) return null; - if (selectedSourceRows.Count != 1) + if (selectedSourceItems.Count != 1) return null; - string name = (selectedSourceRows[0].DataBoundItem as ISourceItem).Name; + string name = selectedSourceItems[0].Name; Uri inputUri = new Uri(String.Format("{0}/{1}", Configuration.Source.Local.Address.LocalPath, name)); return new FileInfo(inputUri.LocalPath); } diff --git a/client/Maestro/MaestroForm.Target.cs b/client/Maestro/MaestroForm.Target.cs index cad5a5e3..8d1a646f 100644 --- a/client/Maestro/MaestroForm.Target.cs +++ b/client/Maestro/MaestroForm.Target.cs @@ -2,14 +2,13 @@ using System; using System.Linq; using System.Windows.Forms; -using Maestro.Metadata; using System.Collections.Generic; using TrafficClient; using MaestroShared.Configuration; using MaestroShared.Metadata; using MaestroShared.Targets; using MaestroShared.Target; -using System.Reflection; +using System.Diagnostics; namespace Maestro { @@ -51,6 +50,17 @@ namespace Maestro { private void OnChecked(CheckBox checkBox, Target target) { if (checkBox.Checked) { List processors = CreateProcessors(target, checkBox); + foreach (ITargetProcessor processor in processors) { + if (processor.Parameters.TargetConfig.Reference != null) { + foreach (String reference in processor.Parameters.TargetConfig.Reference) { + var key = currentProcessors.Keys.Where(c => c.Text.Equals(reference)).SingleOrDefault(); + var referencedProcessor = currentProcessors[key]?.Where(p => p.Input.Equals(processor.Input)).SingleOrDefault(); + if (referencedProcessor != null) + processor.AddReference(referencedProcessor); + } + } + } + if (processors != null && processors.Count > 0) { if (currentProcessors.ContainsKey(checkBox)) currentProcessors[checkBox].AddRange(processors); @@ -66,8 +76,8 @@ namespace Maestro { private List CreateProcessors(Target target, CheckBox checkBox) { List result = null; - foreach (DataGridViewRow actualRow in selectedSourceRows) { - ISourceItem sourceItem = actualRow.DataBoundItem as ISourceItem; + foreach (ISourceItem sourceItem in selectedSourceItems) { + //ISourceItem sourceItem = actualRow.DataBoundItem as ISourceItem; if (sourceItem == null) continue; if (!EnsureSegments(target)) { @@ -85,7 +95,10 @@ namespace Maestro { if (result == null) result = new List(); result.Add(processor); + + //var beforeProcessors = new Dictionary>(currentProcessors); HandleCheckBoxReferences(target.Reference, true); + //var diff = beforeProcessors.Except(currentProcessors).Concat(currentProcessors.Except(beforeProcessors)); } return result; } @@ -158,17 +171,23 @@ namespace Maestro { }; } - private void HandleCheckBoxReferences(string reference, bool check) { - if (String.IsNullOrEmpty(reference)) - return; + private List HandleCheckBoxReferences(string[] reference, bool check) { + if (reference == null || reference.Length == 0) + return null; var controlls = panelActions.Controls; + List result = null; foreach (Control actual in controlls) { - if (actual is CheckBox actualCheckbox && actualCheckbox.Text.Equals(reference)) { - if (check) + if (actual is CheckBox actualCheckbox && reference.Contains(actualCheckbox.Text)) { + if (check) { actualCheckbox.Checked = check; + if (result == null) + result = new List(); + result.Add(actualCheckbox); + } actualCheckbox.Enabled = !check; } } + return result; } private ISourceItem GetSourceItemFromBindingSource(string actual) { @@ -204,11 +223,18 @@ namespace Maestro { } private void OnExecuteClick(object sender, EventArgs e) { - foreach (var element in currentProcessors) { - foreach (ITargetProcessor processor in element.Value) { - jobs.Add(processor); - jobsQueue.Enqueue(processor); - } + IEnumerable keys = currentProcessors.Keys.OrderByDescending(k => (k.Tag as Target).NexioServer); + if (keys == null) + return; + + foreach (var key in keys) { + List targetProcessors = currentProcessors[key]; + if (targetProcessors == null) + continue; + targetProcessors.ForEach(p => { + jobs.Add(p); + jobsQueue.Enqueue(p); + }); } ClearSelectedProcessors(); diff --git a/client/Maestro/MaestroForm.cs b/client/Maestro/MaestroForm.cs index ff6c5b8b..860ec07c 100644 --- a/client/Maestro/MaestroForm.cs +++ b/client/Maestro/MaestroForm.cs @@ -245,5 +245,6 @@ namespace Maestro { break; } } + } } diff --git a/client/Maestro/MaestroForm.resx b/client/Maestro/MaestroForm.resx index c8aa6e9d..cd7a5716 100644 --- a/client/Maestro/MaestroForm.resx +++ b/client/Maestro/MaestroForm.resx @@ -128,7 +128,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACc - BwAAAk1TRnQBSQFMAwEBAAEYAQABGAEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA + BwAAAk1TRnQBSQFMAwEBAAFAAQABQAEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm diff --git a/client/Maestro/Program.cs b/client/Maestro/Program.cs index c82e2281..37e2f74f 100644 --- a/client/Maestro/Program.cs +++ b/client/Maestro/Program.cs @@ -14,7 +14,6 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -29,7 +28,8 @@ namespace Maestro { [STAThread] static void Main() { string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString(); - string mutexId = string.Format("Global\\{{{0}}}", appGuid); + string userName = WindowsIdentity.GetCurrent().Name; + string mutexId = string.Format("Global\\{0}-{1}", appGuid, userName.Replace('\\', '-')); bool createdNew; var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var securitySettings = new MutexSecurity(); @@ -257,17 +257,21 @@ namespace Maestro { ContextMenu = new ContextMenu(menuItems.ToArray()), Visible = true }; - //trayIcon.Click += TrayIcon_Click; + trayIcon.Click += OnTrayIconClick; } - private void TrayIcon_Click(object sender, EventArgs e) { - MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic); - try { - mi.Invoke(sender as NotifyIcon, null); - } - catch (Exception ex) { } + private void OnTrayIconClick(object sender, EventArgs e) { + ShowAllForms(); } + //private void TrayIcon_Click(object sender, EventArgs e) { + // MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic); + // try { + // mi.Invoke(sender as NotifyIcon, null); + // } + // catch (Exception ex) { } + //} + private void ShowAllForms() { foreach (MeastroFormNotifyIcon form in forms) { form.ShowForm(); diff --git a/client/Maestro/Properties/AssemblyInfo.cs b/client/Maestro/Properties/AssemblyInfo.cs index 99c27c59..8d42e911 100644 --- a/client/Maestro/Properties/AssemblyInfo.cs +++ b/client/Maestro/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.2.1")] -[assembly: AssemblyFileVersion("2.0.2.1")] +[assembly: AssemblyVersion("2.0.3.1")] +[assembly: AssemblyFileVersion("2.0.3.1")] diff --git a/client/Maestro/Sources/FileSystemSource.cs b/client/Maestro/Sources/FileSystemSource.cs index f635e17b..ec49526b 100644 --- a/client/Maestro/Sources/FileSystemSource.cs +++ b/client/Maestro/Sources/FileSystemSource.cs @@ -131,6 +131,12 @@ namespace Maestro.Sources { } public void RemoveFilter() { + Reset(null); + } + + public void Reset(string path) { + if (path != null) + this.path = path; Clear(); cache = null; Shutdown(); diff --git a/client/Maestro/Splash.cs b/client/Maestro/Splash.cs index df785bd1..f855cdf4 100644 --- a/client/Maestro/Splash.cs +++ b/client/Maestro/Splash.cs @@ -9,7 +9,7 @@ namespace Maestro { InitializeComponent(); Version version = Assembly.GetEntryAssembly().GetName().Version; labelVersion.ForeColor = Color.White; - labelVersion.Text = String.Format("v{0}.{1}.{2}", version.Major, version.Minor, version.Build); + labelVersion.Text = String.Format("v{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision); } private void splashTimer_Tick(object sender, EventArgs e) { diff --git a/client/MaestroShared/Configuration/ConfigurationInfo.cs b/client/MaestroShared/Configuration/ConfigurationInfo.cs index f6d6135b..5f3cf2b0 100644 --- a/client/MaestroShared/Configuration/ConfigurationInfo.cs +++ b/client/MaestroShared/Configuration/ConfigurationInfo.cs @@ -74,7 +74,7 @@ namespace MaestroShared.Configuration { public bool SendEmailOnSuccess { get; set; } public string SuccessEmailRecipient { get; set; } public string SuccessEmailPattern { get; set; } - public string Reference { get; set; } + public string[] Reference { get; set; } public bool NexioServer { get; set; } public string NexioFileExistsMessage { get; set; } public string Agency { get; set; } @@ -96,6 +96,7 @@ namespace MaestroShared.Configuration { } public class UNCSource : Source { + public bool FoldersAutoExpand { get; set; } } public class NEXIOSource : Source { diff --git a/client/MaestroShared/Targets/ITargetProcessor.cs b/client/MaestroShared/Targets/ITargetProcessor.cs index 977f726d..da99cf59 100644 --- a/client/MaestroShared/Targets/ITargetProcessor.cs +++ b/client/MaestroShared/Targets/ITargetProcessor.cs @@ -5,6 +5,7 @@ using System.Windows.Forms; namespace MaestroShared.Targets { public interface ITargetProcessor : INotifyPropertyChanged { + void AddReference(ITargetProcessor reference); TargetProcessorParameter Parameters { get; } DateTime Started { get; set; } DateTime Finished { get; set; } diff --git a/client/MaestroShared/Targets/TargetProcessor.cs b/client/MaestroShared/Targets/TargetProcessor.cs index 19dc09e6..dbff9690 100644 --- a/client/MaestroShared/Targets/TargetProcessor.cs +++ b/client/MaestroShared/Targets/TargetProcessor.cs @@ -1,7 +1,9 @@ using MaestroShared.Commons; using MaestroShared.Target; using System; +using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Windows.Forms; @@ -25,6 +27,8 @@ namespace MaestroShared.Targets { private string label; private string killDatePath; protected Control parent; + private List references; + public event PropertyChangedEventHandler PropertyChanged; public virtual void Initialize(Control parent, TargetProcessorParameter parameters) { @@ -43,6 +47,19 @@ namespace MaestroShared.Targets { protected virtual void ExecuteCompleted() { } + public void AddReference(ITargetProcessor reference) { + if (references == null) + references = new List(); + if (!references.Contains(reference)) { + Debug.WriteLine(String.Format("Adding {0} [{1}] to {2} [{3}]", reference.Parameters.TargetConfig.Label, reference.Input, Parameters.TargetConfig.Label, Input)); + references.Add(reference); + } + } + + private void RevokeReferences() { + references?.ForEach(i => i.Status = REVOKED); + } + public TargetProcessorParameter Parameters { get; internal set; } public string Status { @@ -53,6 +70,8 @@ namespace MaestroShared.Targets { if (status != value) { status = value; NotifyPropertyChanged(); + if (Status == REVOKED || Status == ERROR) + RevokeReferences(); } } } diff --git a/server/-product/pom.xml b/server/-product/pom.xml index f02b54d0..8904badb 100644 --- a/server/-product/pom.xml +++ b/server/-product/pom.xml @@ -300,7 +300,7 @@ "synchronize remote" "mkdir log" "call chmod +x mediacube" - "call pcs resource enable mediacube_script" + diff --git a/server/user.jobengine.executors/config/scheduledjobs.json b/server/user.jobengine.executors/config/scheduledjobs.json index a460ac63..f84835ab 100644 --- a/server/user.jobengine.executors/config/scheduledjobs.json +++ b/server/user.jobengine.executors/config/scheduledjobs.json @@ -70,7 +70,7 @@ "name" : "OCTOPUS adatok szinkronizálása", "template": "sync-octopus.xml", "executeimmediate": true, - "cronexpression": "0 0/1 * * * ?", + "cronexpression": "0/20 * * * * ?", "parameters": [ {"name": "forceFull", "value": false, "type": "java.lang.Boolean"} ] @@ -80,7 +80,7 @@ "name" : "OCTOPUS adatok teljes szinkronizálása", "template": "sync-octopus.xml", "executeimmediate": false, - "cronexpression": "#0 0/1 * * * ?", + "cronexpression": "#0/20 * * * * ?", "parameters": [ {"name": "forceFull", "value": true, "type": "java.lang.Boolean"} ] diff --git a/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusAPI.java b/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusAPI.java index daa69089..a6824a92 100644 --- a/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusAPI.java +++ b/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusAPI.java @@ -21,11 +21,11 @@ import user.commons.CalendarUtils; import user.commons.nosql.NoSQLUtils; public class OctopusAPI implements IOctopusAPI { - private static final String RUNDOWN = "rundown"; private static final Logger logger = LogManager.getLogger(); private static final String ID = "id"; private static final String STORY_FOLDER = "story_folder"; private static final String MOS_OBJECTS = "mosObjects"; + private static final String RUNDOWN = "rundown"; public static final String RUNDOWN_COLLECTION_NAME = "rundowns"; public static final String STORY_COLLECTION_NAME = "stories"; public static final String STORY_FOLDER_COLLECTION_NAME = "story_folders"; diff --git a/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusDataMiner.java b/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusDataMiner.java index 3ae3c16a..09ab483c 100644 --- a/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusDataMiner.java +++ b/server/user.jobengine.osgi.commons/src/user/commons/octopus/OctopusDataMiner.java @@ -83,11 +83,11 @@ public class OctopusDataMiner implements Runnable { private static final String STARTING = "Starting"; private static final String STORYID = "storyId"; - public static final String RUNDOWN_COLLECTION_NAME = "rundowns"; - public static final String STORY_COLLECTION_NAME = "stories"; - public static final String STORY_FOLDER_COLLECTION_NAME = "story_folders"; - public static final String TIME_COLLECTION_NAME = "time"; - public static final String LASTUPDATE_TIME = "lastUpdateTime"; + public static String RUNDOWN_COLLECTION_NAME = "rundowns"; + public static String STORY_COLLECTION_NAME = "stories"; + public static String STORY_FOLDER_COLLECTION_NAME = "story_folders"; + public static String TIME_COLLECTION_NAME = "time"; + public static String LASTUPDATE_TIME = "lastUpdateTime"; private DB db; private ResteasyWebTarget webTarget; @@ -100,6 +100,7 @@ public class OctopusDataMiner implements Runnable { private Map storyStoryFolders; private Map storedStoryRundowns; private Map storedStoryStoryFolders; + private Map storedStoryMosObjects; public OctopusDataMiner() { String jdbcUrl = System.getProperty("jobengine.nosql.db.url"); @@ -160,7 +161,7 @@ public class OctopusDataMiner implements Runnable { private void buildStoriesReferences() { DBCollection collection = db.getCollection(STORY_COLLECTION_NAME); - DBCursor cursor = collection.find(null, new BasicDBObject(ID, 1).append(REF_RUNDOWN, 1).append(REF_STORYFOLDER, 1)); + DBCursor cursor = collection.find(null, new BasicDBObject(ID, 1).append(REF_RUNDOWN, 1).append(REF_STORYFOLDER, 1).append(MOS_OBJECTS, 1)); //DBCursor find = collection.find(QueryBuilder.start(ID).greaterThan(0).get()); try { @@ -179,6 +180,13 @@ public class OctopusDataMiner implements Runnable { storedStoryStoryFolders = new HashMap<>(); storedStoryStoryFolders.put(storyId, storyFolderRef); } + + BasicDBList storyMosObjects = asDBList(story, MOS_OBJECTS); + if (storyMosObjects != null) { + if (storedStoryMosObjects == null) + storedStoryMosObjects = new HashMap<>(); + storedStoryMosObjects.put(storyId, storyMosObjects); + } } } catch (Exception e) { logger.catching(e); @@ -496,9 +504,27 @@ public class OctopusDataMiner implements Runnable { } public void run(boolean forceFull) { - if (forceFull) + if (forceFull) { + // RUNDOWN_COLLECTION_NAME = "rundowns_tmp"; + // STORY_COLLECTION_NAME = "stories_tmp"; + // STORY_FOLDER_COLLECTION_NAME = "storyfolders_tmp"; + // TIME_COLLECTION_NAME = "octopusSyncTime_tmp"; clear(); + } run(); + // if (forceFull) { + // RUNDOWN_COLLECTION_NAME = "rundowns"; + // STORY_COLLECTION_NAME = "stories"; + // STORY_FOLDER_COLLECTION_NAME = "storyfolders"; + // TIME_COLLECTION_NAME = "octopusSyncTime"; + // db.getCollection("rundowns_tmp").rename(RUNDOWN_COLLECTION_NAME, true); + // db.getCollection("stories_tmp").rename(STORY_COLLECTION_NAME, true); + // db.getCollection("storyfolders_tmp").rename(STORY_FOLDER_COLLECTION_NAME, true); + // db.getCollection("octopusSyncTime_tmp").rename(TIME_COLLECTION_NAME, true); + // //clear(); + // } + + //TODO reset collection names } public void setLastUpdateTime(Date lastUpdateTime) { @@ -570,6 +596,8 @@ public class OctopusDataMiner implements Runnable { rundownRef = (rundownRef == null) ? new BasicDBList() : rundownRef; BasicDBList storyFolderRef = storyStoryFolders.get(storyID); storyFolderRef = (storyFolderRef == null) ? new BasicDBList() : storyFolderRef; + BasicDBList modifiedMOS = GetRelevantMOSObjects(story); + modifiedMOS = (modifiedMOS == null) ? new BasicDBList() : modifiedMOS; boolean uptodate = true; if (!isModified(lastUpdateTime, story)) { @@ -582,6 +610,13 @@ public class OctopusDataMiner implements Runnable { storedStoryFolderRef = (storedStoryFolderRef == null) ? new BasicDBList() : storedStoryFolderRef; uptodate = storedStoryFolderRef.equals(storyFolderRef); } + + if (uptodate) { + BasicDBList storedMOS = storedStoryMosObjects.get(storyID); + storedMOS = (storedMOS == null) ? new BasicDBList() : storedMOS; + uptodate = storedMOS.equals(modifiedMOS); + } + if (uptodate) return; } @@ -598,7 +633,6 @@ public class OctopusDataMiner implements Runnable { story.put(REF_STORYFOLDER, storyFolderRef); String scriptContent = GetScriptContent(story); story.put(SCRIPT_CONTENT, scriptContent); - BasicDBList modifiedMOS = GetRelevantMOSObjects(story); if (modifiedMOS == null || modifiedMOS.isEmpty()) { if (story.containsKey(MOS_OBJECTS)) story.remove(MOS_OBJECTS); diff --git a/server/user.jobengine.osgi.commons/test/user/common/octopus/test/OctopusDataMinerTest.java b/server/user.jobengine.osgi.commons/test/user/common/octopus/test/OctopusDataMinerTest.java index 96eac917..65657911 100644 --- a/server/user.jobengine.osgi.commons/test/user/common/octopus/test/OctopusDataMinerTest.java +++ b/server/user.jobengine.osgi.commons/test/user/common/octopus/test/OctopusDataMinerTest.java @@ -1,5 +1,8 @@ package user.common.octopus.test; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.io.FileInputStream; import java.lang.invoke.MethodHandles; import java.net.URL; @@ -132,4 +135,30 @@ public class OctopusDataMinerTest { } } + @Test + public void testListEquals() { + BasicDBList list1 = new BasicDBList(new BasicDBObject("x", 1)); + BasicDBList list2 = new BasicDBList(new BasicDBObject("x", 1)); + + assertTrue(list1.equals(list2)); + } + + @Test + public void testListEquals_fail1() { + BasicDBList list1 = new BasicDBList(new BasicDBObject("x", 1)); + BasicDBList list2 = new BasicDBList(new BasicDBObject("x", "1")); + + assertFalse(list1.equals(list2)); + } + + @Test + public void testListEquals2() { + BasicDBList list1 = new BasicDBList(new BasicDBObject("x", 1)); + list1.add(new BasicDBObject("y", 2)); + list1.add(new BasicDBObject("z", 3)); + BasicDBList list2 = new BasicDBList(new BasicDBObject("x", 1)); + list2.add(new BasicDBObject("y", 2)); + list2.add(new BasicDBObject("z", 3)); + assertTrue(list1.equals(list2)); + } } diff --git a/server/user.jobengine.osgi.server/pages/joblist.zul b/server/user.jobengine.osgi.server/pages/joblist.zul index e8b5abb9..03191576 100644 --- a/server/user.jobengine.osgi.server/pages/joblist.zul +++ b/server/user.jobengine.osgi.server/pages/joblist.zul @@ -37,9 +37,9 @@ onSelect="@command('selectJob')" style="border: none; background: #e3e3e3 !important;" oddRowSclass="listbox-odd-style" sclass="listbox-normal-style" > - + - +