• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

HicServices / RDMP / 16571947926

28 Jul 2025 02:34PM UTC coverage: 57.464% (+0.04%) from 57.422%
16571947926

push

github

web-flow
Merge pull request #2215 from HicServices/task/rdmp-323-right-click

Task/rdmp 323 right click

11430 of 21415 branches covered (53.37%)

Branch coverage included in aggregate %.

30 of 43 new or added lines in 12 files covered. (69.77%)

4 existing lines in 3 files now uncovered.

32398 of 54855 relevant lines covered (59.06%)

17622.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.29
/Rdmp.Core/CommandExecution/GoToCommandFactory.cs
1
// Copyright (c) The University of Dundee 2018-2024
2
// This file is part of the Research Data Management Platform (RDMP).
3
// RDMP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4
// RDMP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5
// You should have received a copy of the GNU General Public License along with RDMP. If not, see <https://www.gnu.org/licenses/>.
6

7
using System;
8
using System.Collections.Generic;
9
using System.Linq;
10
using Rdmp.Core.CommandExecution.AtomicCommands;
11
using Rdmp.Core.Curation.Data;
12
using Rdmp.Core.Curation.Data.Aggregation;
13
using Rdmp.Core.Curation.Data.Cohort;
14
using Rdmp.Core.Curation.Data.Dashboarding;
15
using Rdmp.Core.Curation.Data.DataLoad;
16
using Rdmp.Core.Curation.Data.Governance;
17
using Rdmp.Core.Curation.Data.ImportExport;
18
using Rdmp.Core.DataExport.Data;
19
using Rdmp.Core.Icons.IconProvision;
20
using Rdmp.Core.MapsDirectlyToDatabaseTable;
21
using Rdmp.Core.MapsDirectlyToDatabaseTable.Injection;
22
using Rdmp.Core.Providers;
23
using SixLabors.ImageSharp;
24
using SixLabors.ImageSharp.PixelFormats;
25

26
namespace Rdmp.Core.CommandExecution;
27

28
/// <summary>
29
/// Builds the "Go To" submenu for travelling between objects in an RDMP database (e.g. Catalogue to extractions using the Catalogue)
30
/// </summary>
31
public class GoToCommandFactory : CommandFactoryBase
32
{
33
    private readonly IBasicActivateItems _activator;
34
    public const string GoTo = "Go To";
35

36
    public GoToCommandFactory(IBasicActivateItems activator)
198✔
37
    {
38
        _activator = activator;
198✔
39
    }
198✔
40

41
    public IEnumerable<IAtomicCommand> GetCommands(object forObject)
42
    {
43
        //forget old values, get them up to the minute
44
        if (Is(forObject, out IInjectKnown ii))
198✔
45
            ii.ClearAllInjections();
90✔
46

47
        if (Is(forObject, out IMapsDirectlyToDatabaseTable mt))
198✔
48
        {
49
            // Go to import / export definitions
50
            var export = _activator.CoreChildProvider.AllExports.FirstOrDefault(export => export.IsReferenceTo(mt));
51

52
            if (export != null)
192!
53
                yield return new ExecuteCommandShow(_activator, export, 0, true)
×
54
                { OverrideCommandName = "Show Export Definition" };
×
55

56
            var import = _activator.RepositoryLocator.CatalogueRepository.GetReferencesTo<ObjectImport>(mt)
192✔
57
                .FirstOrDefault();
192✔
58
            if (import != null)
192!
59
                yield return new ExecuteCommandShow(_activator, import, 0)
×
60
                { OverrideCommandName = "Show Import Definition" };
×
61

62
            if (SupportsReplacement(forObject))
192✔
63
                yield return new ExecuteCommandShow(_activator, () => GetReplacementIfAny(mt))
64
                { OverrideCommandName = "Replacement" };
190✔
65

66

67
            yield return new ExecuteCommandSimilar(_activator, mt, false) { GoTo = true };
192✔
68
        }
69

70
        // cic => associated projects
71
        if (Is(forObject, out CohortIdentificationConfiguration cic))
198✔
72
            yield return new ExecuteCommandShow(_activator, () =>
2✔
73
            {
2✔
74
                return _activator.CoreChildProvider is DataExportChildProvider { AllProjectAssociatedCics: not null } dx
75
                    ? dx.AllProjectAssociatedCics.Where(a => a.CohortIdentificationConfiguration_ID == cic.ID)
76
                        .Select(a => a.Project).Distinct()
×
77
                    : Array.Empty<CohortIdentificationConfiguration>();
78
            })
2✔
79
            {
2✔
80
                OverrideCommandName = "Project(s)",
2✔
81
                OverrideIcon = GetImage(RDMPConcept.Project)
2✔
82
            };
2✔
83

84
        if (Is(forObject, out ColumnInfo columnInfo))
198✔
85
        {
86
            yield return new ExecuteCommandSimilar(_activator, columnInfo, true)
4✔
87
            {
4✔
88
                OverrideCommandName = "Different",
4✔
89
                GoTo = true,
4✔
90
                OverrideIcon = GetImage(RDMPConcept.ColumnInfo)
4✔
91
            };
4✔
92

93
            yield return new ExecuteCommandShow(_activator, columnInfo.TableInfo_ID, typeof(TableInfo))
4✔
94
            {
4✔
95
                OverrideCommandName = "Table Info",
4✔
96
                OverrideIcon = GetImage(RDMPConcept.TableInfo)
4✔
97
            };
4✔
98
            yield return new ExecuteCommandShow(_activator,
4✔
99
                () => _activator.CoreChildProvider.AllCatalogueItems.Where(catItem =>
100
                    catItem.ColumnInfo_ID == columnInfo.ID))
101
            {
4✔
102
                OverrideCommandName = "Catalogue Item(s)",
4✔
103
                OverrideIcon = GetImage(RDMPConcept.CatalogueItem)
4✔
104
            };
4✔
105

106
            yield return new ExecuteCommandShow(_activator, columnInfo.ANOTable_ID, typeof(ANOTable))
4✔
107
            {
4✔
108
                OverrideCommandName = "ANO Table",
4✔
109
                OverrideIcon = GetImage(RDMPConcept.ANOTable)
4✔
110
            };
4✔
111
        }
112

113
        if (Is(forObject, out ExtractionInformation ei))
198✔
114
        {
115
            yield return new ExecuteCommandShow(_activator, ei.CatalogueItem?.Catalogue_ID, typeof(Catalogue))
2!
116
            {
2✔
117
                OverrideCommandName = "Catalogue",
2✔
118
                OverrideIcon = GetImage(RDMPConcept.Catalogue)
2✔
119
            };
2✔
120
            yield return new ExecuteCommandShow(_activator, ei.CatalogueItem_ID, typeof(CatalogueItem))
2✔
121
            {
2✔
122
                OverrideCommandName = "Catalogue Item",
2✔
123
                OverrideIcon = GetImage(RDMPConcept.CatalogueItem)
2✔
124
            };
2✔
125
            yield return new ExecuteCommandShow(_activator, ei.ColumnInfo, 0, true)
2✔
126
            {
2✔
127
                OverrideCommandName = "Column Info",
2✔
128
                OverrideIcon = GetImage(RDMPConcept.ColumnInfo)
2✔
129
            };
2✔
130
        }
131

132
        if (Is(forObject, out CatalogueItem ci))
198✔
133
        {
134
            yield return new ExecuteCommandShow(_activator, ci.Catalogue_ID, typeof(Catalogue))
14✔
135
            {
14✔
136
                OverrideCommandName = "Catalogue",
14✔
137
                OverrideIcon = GetImage(RDMPConcept.Catalogue)
14✔
138
            };
14✔
139
            yield return new ExecuteCommandShow(_activator, ci.ExtractionInformation, 0, true)
14✔
140
            {
14✔
141
                OverrideCommandName = "Extraction Information",
14✔
142
                OverrideIcon = GetImage(RDMPConcept.ExtractionInformation)
14✔
143
            };
14✔
144
            yield return new ExecuteCommandShow(_activator, ci.ColumnInfo, 0, true)
14✔
145
            {
14✔
146
                OverrideCommandName = "Column Info",
14✔
147
                OverrideIcon = GetImage(RDMPConcept.ColumnInfo)
14✔
148
            };
14✔
149
        }
150

151
        if (Is(forObject, out ExtractableDataSet eds))
198!
152
        {
153
            yield return new ExecuteCommandShow(_activator, eds.Catalogue_ID, typeof(Catalogue))
×
154
            {
×
155
                OverrideCommandName = "Catalogue",
×
156
                OverrideIcon = GetImage(RDMPConcept.Catalogue)
×
157
            };
×
158

159
            yield return new ExecuteCommandShow(_activator, () =>
×
160
            {
×
161
                return _activator.CoreChildProvider is DataExportChildProvider dx
162
                    ? dx.SelectedDataSets.Where(s => s.ExtractableDataSet_ID == eds.ID)
163
                        .Select(s => s.ExtractionConfiguration)
×
164
                    : Array.Empty<SelectedDataSets>();
165
            })
×
166
            {
×
167
                OverrideCommandName = "Extraction Configuration(s)",
×
168
                OverrideIcon = GetImage(RDMPConcept.ExtractionConfiguration)
×
169
            };
×
170
        }
171

172
        if (Is(forObject, out GovernancePeriod period))
198✔
173
            yield return new ExecuteCommandShow(_activator, () => period.GovernedCatalogues)
174
            { OverrideCommandName = "Catalogue(s)", OverrideIcon = GetImage(RDMPConcept.Catalogue) };
2✔
175

176
        if (Is(forObject, out JoinInfo j))
198!
177
            yield return new ExecuteCommandShow(_activator, j.ForeignKey_ID, typeof(ColumnInfo))
×
178
            { OverrideCommandName = "Foreign Key", OverrideIcon = GetImage(RDMPConcept.ColumnInfo) };
×
179

180
        if (Is(forObject, out Lookup lookup))
198✔
181
        {
182
            yield return new ExecuteCommandShow(_activator, lookup.Description.TableInfo_ID, typeof(TableInfo));
6✔
183
            yield return new ExecuteCommandShow(_activator, lookup.ForeignKey_ID, typeof(ColumnInfo))
6✔
184
            { OverrideCommandName = "Foreign Key", OverrideIcon = GetImage(RDMPConcept.ColumnInfo) };
6✔
185
        }
186

187
        if (Is(forObject, out ExtractionFilter masterFilter))
198!
188
        {
189
            yield return new ExecuteCommandShow(_activator, () =>
×
NEW
190
                _activator.CoreChildProvider.AllAggregateFilters.Where(af => af.ClonedFromExtractionFilter_ID == masterFilter.ID).Select(f => f.GetAggregate())
×
191
                    .Where(a => a != null).Distinct()
×
192
            )
×
193
            { OverrideCommandName = "Usages (in Cohort Builder)" };
×
194

UNCOV
195
            yield return new ExecuteCommandShow(_activator, () =>
×
196
                _activator.RepositoryLocator.DataExportRepository
197
                    .GetAllObjectsWhere<DeployedExtractionFilter>("ClonedFromExtractionFilter_ID", masterFilter.ID)
198
                    .Select(f => f.GetDataset()?.ExtractionConfiguration)
×
199
                    .Where(c => c != null).Distinct()
×
200
            )
×
201
            { OverrideCommandName = "Usages (in Extractions)" };
×
202
        }
203

204
        if (Is(forObject, out IFilter filter) && filter.ClonedFromExtractionFilter_ID.HasValue)
198!
205
        {
206
            ExtractionFilter parent = null;
×
207

208
            try
209
            {
210
                parent = _activator.RepositoryLocator.CatalogueRepository.GetObjectByID<ExtractionFilter>(
×
211
                    filter.ClonedFromExtractionFilter_ID.Value);
×
212
            }
×
213
            catch (KeyNotFoundException)
×
214
            {
215
                // new ImpossibleCommand("Parent filter has been deleted") { OverrideCommandName = "Parent Filter" };
216
            }
×
217

218
            if (parent != null)
×
219
                yield return new ExecuteCommandShow(_activator, parent, 0)
×
220
                { OverrideCommandName = "Parent Filter", OverrideIcon = GetImage(RDMPConcept.Filter) };
×
221
        }
222

223
        if (Is(forObject, out SelectedDataSets selectedDataSet))
198✔
224
        {
225
            yield return new ExecuteCommandShow(_activator, selectedDataSet.ExtractableDataSet.Catalogue_ID,
14✔
226
                typeof(Catalogue))
14✔
227
            {
14✔
228
                OverrideCommandName = "Catalogue",
14✔
229
                OverrideIcon = GetImage(RDMPConcept.Catalogue)
14✔
230
            };
14✔
231

232
            var ep = selectedDataSet.ExtractionProgressIfAny;
14✔
233
            if (ep != null) yield return new ExecuteCommandShow(_activator, ep, 0, true);
14!
234
        }
235

236
        if (Is(forObject, out TableInfo tableInfo))
198✔
237
            yield return new ExecuteCommandShow(_activator,
4✔
238
                () => tableInfo.ColumnInfos.SelectMany(c =>
239
                    _activator.CoreChildProvider.AllCatalogueItems.Where(catItem => catItem.ColumnInfo_ID == c.ID)
240
                        .Select(catItem => catItem.Catalogue)).Distinct())
×
241
            {
4✔
242
                OverrideCommandName = "Catalogue(s)",
4✔
243
                OverrideIcon = GetImage(RDMPConcept.Catalogue)
4✔
244
            };
4✔
245

246
        if (Is(forObject, out AggregateConfiguration aggregate))
198✔
247
        {
248
            yield return new ExecuteCommandShow(_activator, aggregate.GetCohortIdentificationConfigurationIfAny()?.ID,
14!
249
                typeof(CohortIdentificationConfiguration))
14✔
250
            {
14✔
251
                OverrideCommandName = "Cohort Identification Configuration",
14✔
252
                OverrideIcon = GetImage(RDMPConcept.CohortIdentificationConfiguration)
14✔
253
            };
14✔
254
            yield return new ExecuteCommandShow(_activator, aggregate.Catalogue_ID, typeof(Catalogue))
14✔
255
            {
14✔
256
                OverrideCommandName = "Catalogue",
14✔
257
                OverrideIcon = GetImage(RDMPConcept.Catalogue)
14✔
258
            };
14✔
259
        }
260

261
        if (Is(forObject, out Catalogue catalogue))
198✔
262
        {
263
            var lmdLinkage = _activator.CoreChildProvider.AllLoadMetadataCatalogueLinkages.Where(lmdcl => lmdcl.CatalogueID == catalogue.ID).Select(lmdcl => lmdcl.LoadMetadataID);
2,500✔
264
            var lmds = _activator.CoreChildProvider.AllLoadMetadatas.Where(lmd => lmdLinkage.Contains(lmd.ID));
344✔
265
            foreach (var lmd in lmds)
72!
266
            {
267
                yield return new ExecuteCommandShow(_activator, lmd.ID, typeof(LoadMetadata))
×
268
                { OverrideCommandName = $"Data Load ({lmd.Name})", OverrideIcon = GetImage(RDMPConcept.LoadMetadata) };
×
269
            }
270
            if (!lmds.Any())
36✔
271
            {
272
                yield return new ExecuteCommandShow(_activator, null, typeof(LoadMetadata))
36✔
273
                { OverrideCommandName = "No Data Load", OverrideIcon = GetImage(RDMPConcept.LoadMetadata) };
36✔
274
            }
275

276

277
            if (_activator.CoreChildProvider is DataExportChildProvider exp)
36✔
278
            {
279
                var cataEds = exp.ExtractableDataSets.Where(d => d.Catalogue_ID == catalogue.ID);
280

281
                if (cataEds != null)
36!
282
                {
283
                    yield return new ExecuteCommandShow(_activator,
36✔
284
                         () => (cataEds.SelectMany(c => c.Projects.Select(p => p.ID)).Select(p => _activator.RepositoryLocator.DataExportRepository.GetObjectByID<Project>(p))))
×
285
                    {
36✔
286
                        OverrideCommandName = "Associated Projects",
36✔
287
                        OverrideIcon = GetImage(RDMPConcept.Project)
36✔
288
                    };
36✔
289
                    yield return new ExecuteCommandShow(_activator,
36✔
290
                          () => (cataEds.SelectMany(c => c.ExtractionConfigurations.Select(e => e.Project))))
×
291
                    {
36✔
292
                        OverrideCommandName = "Extracted In (Project)",
36✔
293
                        OverrideIcon = GetImage(RDMPConcept.Project)
36✔
294
                    };
36✔
295
                    yield return new ExecuteCommandShow(_activator, () => cataEds.SelectMany(c => c.ExtractionConfigurations))
36✔
296
                    {
36✔
297
                        OverrideCommandName = $"Extracted In (Extraction Configuration)",
36✔
298
                        OverrideIcon = GetImage(RDMPConcept.ExtractionConfiguration)
36✔
299
                    };
36✔
300
                }
301
                else
302
                {
303
                    //no values, show disabled options
304
                    yield return new ExecuteCommandShow(_activator,
×
305
                          () =>
×
306
                          {
×
307
                              return new Project[] { };
×
308
                          }
×
309
                      )
×
310
                    {
×
311
                        OverrideCommandName = "No Associated Project",
×
312
                        OverrideIcon = GetImage(RDMPConcept.Project)
×
313
                    };
×
314
                    yield return new ExecuteCommandShow(_activator,
×
315
                                             () =>
×
316
                                             {
×
317
                                                 return new Project[] { };
×
318
                                             }
×
319
                                         )
×
320
                    {
×
321
                        OverrideCommandName = "Not Extracted In (Project)",
×
322
                        OverrideIcon = GetImage(RDMPConcept.Project)
×
323
                    };
×
324
                    yield return new ExecuteCommandShow(_activator,
×
325
                        () =>
×
326
                        {
×
327
                            return new ExtractionConfiguration[] { };
×
328
                        }
×
329
                    )
×
330
                    {
×
331
                        OverrideCommandName = "Not Extracted In (Extraction Configuration)",
×
332
                        OverrideIcon = GetImage(RDMPConcept.ExtractionConfiguration)
×
333
                    };
×
334
                }
335
            }
36✔
336

337
            yield return new ExecuteCommandShow(_activator, () => catalogue.GetTableInfoList(true))
338
            { OverrideCommandName = "Table(s)", OverrideIcon = GetImage(RDMPConcept.TableInfo) };
36✔
339

340
            yield return new ExecuteCommandShow(_activator,
36✔
341
                () =>
36✔
342
                    _activator
343
                        .CoreChildProvider
344
                        .AllAggregateConfigurations.Where(ac =>
345
                            ac.IsCohortIdentificationAggregate && ac.Catalogue_ID == catalogue.ID)
346
                        .Select(ac => ac.GetCohortIdentificationConfigurationIfAny())
×
347
                        .Where(cataCic => cataCic != null)
×
348
                        .Distinct())
349
            {
36✔
350
                OverrideCommandName = "Cohort Identification Configuration(s)",
36✔
351
                OverrideIcon = GetImage(RDMPConcept.CohortIdentificationConfiguration)
36✔
352
            };
36✔
353

354

355
            yield return new ExecuteCommandShow(_activator,
36✔
356
                () => _activator.CoreChildProvider.AllGovernancePeriods.Where(p =>
357
                    p.GovernedCatalogues.Contains(catalogue)))
358
            {
36✔
359
                OverrideCommandName = "Governance",
36✔
360
                OverrideIcon = GetImage(RDMPConcept.GovernancePeriod)
36✔
361
            };
36✔
362
        }
36✔
363

364
        if (Is(forObject, out ExtractableCohort cohort))
198!
365
        {
366
            yield return new ExecuteCommandShow(_activator, () =>
×
367
            {
×
368
                return _activator.CoreChildProvider is DataExportChildProvider dx
369
                    ? dx.ExtractionConfigurations.Where(ec => ec.Cohort_ID == cohort.ID)
370
                    : (IEnumerable<IMapsDirectlyToDatabaseTable>)Array.Empty<ExtractionConfiguration>();
371
            })
×
372
            {
×
373
                OverrideCommandName = "Extraction Configuration(s)",
×
374
                OverrideIcon = GetImage(RDMPConcept.ExtractionConfiguration)
×
375
            };
×
376

377
            yield return new ExecuteCommandShow(_activator, () =>
×
378
            {
×
379
                return _activator.CoreChildProvider is DataExportChildProvider dx
380
                    ? dx.Projects.Where(p => p.ProjectNumber == cohort.ExternalProjectNumber)
381
                    : (IEnumerable<IMapsDirectlyToDatabaseTable>)Array.Empty<Project>();
382
            })
×
383
            {
×
384
                OverrideCommandName = "Project(s)",
×
385
                OverrideIcon = GetImage(RDMPConcept.Project)
×
386
            };
×
387

388
            var obj = ExtractableCohortAuditLogBuilder.GetObjectIfAny(cohort, _activator.RepositoryLocator);
×
389
            if (obj is not null && obj is CohortIdentificationConfiguration configuration)
×
390
            {
391
                yield return new ExecuteCommandShow(_activator, () =>
×
392
                {
×
393
                    return [configuration];
×
394
                })
×
395
                {
×
396
                    OverrideCommandName = "Cohort Identification Configuration(s)",
×
397
                    OverrideIcon = GetImage(RDMPConcept.CohortIdentificationConfiguration)
×
398
                };
×
399
            }
400

401
        }
×
402

403
        //if it is a masquerader and masquerading as a DatabaseEntity then add a goto the object
404
        if (forObject is IMasqueradeAs masqueraderIfAny)
198!
405
            if (masqueraderIfAny.MasqueradingAs() is DatabaseEntity m)
×
406
                yield return new ExecuteCommandShow(_activator, m, 0, true)
×
407
                { OverrideIcon = _activator.CoreIconProvider.GetImage(m) };
×
408
    }
198✔
409

410
    private static bool SupportsReplacement(object o) => o is not DashboardLayout;
192✔
411

412
    private IEnumerable<IMapsDirectlyToDatabaseTable> GetReplacementIfAny(IMapsDirectlyToDatabaseTable mt)
413
    {
414
        var replacement = _activator.RepositoryLocator.CatalogueRepository
×
415
            .GetAllObjectsWhere<ExtendedProperty>("Name", ExtendedProperty.ReplacedBy)
×
416
            .FirstOrDefault(r => r.IsReferenceTo(mt));
×
417

418
        return replacement == null
×
419
            ? Enumerable.Empty<IMapsDirectlyToDatabaseTable>()
×
420
            : new[] { mt.Repository.GetObjectByID(mt.GetType(), int.Parse(replacement.Value)) };
×
421
    }
422

423
    private Image<Rgba32> GetImage(RDMPConcept concept) => _activator.CoreIconProvider.GetImage(concept);
372✔
424
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc