diff --git a/applications/Unity.AutoUI/.claude/skills/validate-cypress-selectors/SKILL.md b/applications/Unity.AutoUI/.claude/skills/validate-cypress-selectors/SKILL.md new file mode 100644 index 000000000..250395347 --- /dev/null +++ b/applications/Unity.AutoUI/.claude/skills/validate-cypress-selectors/SKILL.md @@ -0,0 +1,59 @@ +--- +name: validate-cypress-selectors +description: Extract and audit Cypress selectors against Unity Grant Manager application markup, and detect when a branch's app-code changes have broken a selector that worked on main. Use when changing Razor/C#/JS markup, Cypress specs, page objects, shared Cypress commands, element IDs, or CSS selectors — or when investigating why a Cypress test started failing after unrelated app changes. +--- + +# Validate Cypress Selectors + +Maintain the selector contract between `applications/Unity.AutoUI` and `applications/Unity.GrantManager`. Run everything from `applications/Unity.AutoUI`. + +## Two modes + +**Full snapshot** — classify every selector in the repo right now: +```bash +npm run selectors:report +``` +Writes `cypress/selectors/registry.json`. Use this to get a baseline understanding, or before/after a change to eyeball the raw counts. + +**Baseline diff (the useful one for "did this branch break something")**: +```bash +npm run selectors:diff # report only +npm run selectors:fix # + dry-run patch preview for fixable regressions +npm run selectors:apply # + write the unambiguous fixes to disk +``` +Compares the current working tree against the **committed baseline** — `cypress/selectors/registry.json` as it exists at `origin/main` (override with `--base `, e.g. `npm run selectors:diff -- --base origin/develop`). It does **not** re-parse git diffs to guess what changed; it re-runs the full scanner on the current tree and compares the resulting per-selector `status` against the baseline's. Anything that got *worse* (`matched` → `missing`, `matched` → `unverified`, etc.) is a regression this branch likely introduced. + +## Interpreting a full-scan entry + +- `matched` — every identifying token (`id`, `data-cy`, `data-testid`) has static evidence in application source. +- `missing` — at least one identifying token has no static evidence. Investigate. +- `unverified` — a structural/class-based CSS selector that can't be proven reliably by static scanning (no identifying token to search for). +- `exempt` — matches a configured ownership rule (`selector-contract.config.json`): external identity-provider markup, framework-generated selectors (Bootstrap-select, Select2, DataTables, SweetAlert2), or Form.io/CHEFS dynamic fields. Outside the static contract by design. +- `syntaxKind` — `css` or `xpath`. Everything today is `css`; `xpath` exists to catch it early if `cy.xpath(...)`-style selectors are ever introduced (they're harder to keep in sync with markup and generally discouraged). + +`matched` only proves the token exists *somewhere* in source — it says nothing about visibility, permission-gating, or runtime reachability. It's a fast static sanity check, not a substitute for actually running the Cypress spec. + +## Diff-mode regression auto-fix — how it decides what's safe to touch + +Only `matched` (baseline) → `missing` (current) regressions are eligible for auto-fix — that's the one transition backed by concrete proof the selector worked before. Pre-existing `missing`/`unverified` entries are left alone; they aren't this branch's fault and guessing at them is out of scope. + +For each eligible regression: +1. Find where the token was matched at baseline (`applicationMatches` in the baseline entry) and the exact line via `git show :`. +2. In the *current* version of that file, score every line for similarity to the old line (word-overlap, with a small proximity bonus toward the original line number — an attribute rename overwhelmingly stays in place rather than the element relocating). +3. **Exactly one clear winner** → propose restoring the missing attribute onto it (inserted right after the tag name, alongside whatever else is there — never replaces existing attributes). +4. **Zero or ambiguous candidates** (e.g. several structurally-identical sibling elements) → reported as "NEEDS REVIEW" with the old-baseline context shown. Never guessed. + +`--apply` only ever writes the unambiguous fixes from step 3. It never touches an ambiguous case, never invents a token value it doesn't have baseline evidence for, and never commits or pushes — it stops at "working tree modified, go review and commit like any other change." Treat an applied fix the same as any other diff: read it, and actually run the relevant Cypress spec before trusting it, since restoring the identifying token proves the selector *resolves* again, not that the element behaves correctly. + +## Workflow + +1. Before editing UI selectors or markup: `npm run selectors:report` to capture a baseline mentally (or diff against origin/main if you want the machine to do it). +2. Prefer a unique `data-cy` attribute for application-owned interactive elements over relying on a plain `#id`. +3. Update application markup and the corresponding Cypress selector together. +4. `npm run selectors:diff` to see what changed relative to `origin/main`. If something regressed, `npm run selectors:fix` to preview a proposed patch, then `npm run selectors:apply` if it looks right — followed by actually running the affected Cypress spec. +5. For anything reported "NEEDS REVIEW," check the rendered page or Cypress scenario by hand — conditional, permission-gated, or JavaScript-generated elements won't resolve automatically. +6. Report unresolved findings; don't hide them by widening `ownershipRules` exemptions in `selector-contract.config.json` just to make a `missing` entry disappear. + +## Keeping the baseline current + +`cypress/selectors/registry.json` is a committed file that's only meaningful if `origin/main`'s copy is kept up to date — regenerate and commit it on `main` after selector-affecting changes land, otherwise `selectors:diff` will compare against a stale snapshot. diff --git a/applications/Unity.AutoUI/cypress/selectors/README.md b/applications/Unity.AutoUI/cypress/selectors/README.md new file mode 100644 index 000000000..670cebd4f --- /dev/null +++ b/applications/Unity.AutoUI/cypress/selectors/README.md @@ -0,0 +1,61 @@ +# Cypress Selector Contract + +Keeps every selector used by the Cypress suite (`applications/Unity.AutoUI/cypress`) cross-checked against the actual application markup (`applications/Unity.GrantManager/src` + `modules`), so a Razor/C#/JS change that quietly removes or renames an `id`/`data-cy`/`data-testid` a test depends on gets caught before it breaks a run. + +All commands below run from `applications/Unity.AutoUI`. + +## What's in this directory + +- **`registry.json`** — generated output, one entry per distinct selector string found in Cypress code. **This file is meant to be committed** on `main`; it's the baseline every branch's `npm run selectors:diff` compares itself against. Regenerate and commit it after selector-affecting changes land on `main`, or the baseline drifts stale. + +## The two tools + +| Command | What it does | +|---|---| +| `npm run selectors:report` | Full snapshot: re-scans everything, writes `registry.json`, prints a summary. No comparison to anything — just "here's the state of the world right now." | +| `npm run selectors:diff` | Compares the current working tree against `registry.json` as it exists on `origin/main`, and reports any selector whose status got *worse* (a regression this branch likely introduced). | +| `npm run selectors:fix` | Same as `selectors:diff`, plus a dry-run preview of the patch it would apply for any regression it can confidently fix. Writes nothing. | +| `npm run selectors:apply` | Same as `selectors:fix`, but actually writes the unambiguous fixes to disk. Never commits, never pushes, never touches an ambiguous case. | + +Pass `-- --base ` to any diff/fix/apply command to compare against something other than `origin/main`. + +## How the full scan works (`scripts/selector-contract.mjs`) + +1. Walks `cypressRoots` (from `selector-contract.config.json`) and parses every `.ts`/`.tsx`/`.js`/`.jsx` file with the TypeScript compiler API, pulling out every string literal passed as the first argument to a selector-shaped call (`cy.get`, `.find`, `.contains`, `.xpath`, etc.) that looks like a selector. +2. Walks `applicationRoots` for `.cshtml`/`.razor`/`.html`/`.cs`/`.js`/`.ts` source. +3. For each selector, extracts identifying tokens (`#id`, `[data-cy=...]`, `[data-testid=...]`) and checks whether that literal token appears anywhere in the app source (`id="..."`, `asp-for="@Model...."` with underscores mapped to dots, etc.). +4. Classifies each selector: + - **status**: `matched` (evidence found) / `missing` (identifying token, no evidence) / `unverified` (no identifying token to check — a structural CSS selector) / `exempt` (matches an `ownershipRules` pattern in `selector-contract.config.json`: identity-provider markup, framework-generated selectors like Bootstrap-select/Select2/DataTables/SweetAlert2, or Form.io/CHEFS dynamic fields). + - **syntaxKind**: `css` or `xpath`. Nothing in this repo uses XPath today — this exists to flag it immediately if it ever shows up, since XPath selectors are harder to keep in sync with markup than `id`/`data-cy`. + +`matched` proves the token exists somewhere in source. It does **not** prove the element is visible, enabled, permission-gated correctly, or on the route the test expects — it's a fast static check, not a substitute for running the spec. + +## How the diff/fix works (`scripts/selector-diff-report.mjs`) + +No git-diff parsing, no guessing at what changed. It just runs the same full scan against the current tree, fetches the baseline `registry.json` via `git show :.../registry.json`, and compares `status` per selector by exact string match. + +- **Regression** = a selector's status is worse now than at baseline. Only `matched → missing` regressions are eligible for auto-fix — that's the one case with concrete proof the selector used to work. +- **Fix candidate search**: for each missing token, look up which file(s) had it at baseline (`applicationMatches` in the baseline entry), pull the exact old line via `git show`, then score every line in the *current* version of that file by word-overlap similarity to the old line (with a small bonus for being near the original line number — renames overwhelmingly stay in place). One clear winner → propose restoring the attribute there. Zero or multiple close-scoring candidates → reported as "NEEDS REVIEW," nothing is touched. +- **`--apply`** only ever writes the unambiguous fixes. It inserts the missing attribute next to whatever's already on that element — it never removes or rewrites existing attributes, never invents a token value without baseline evidence, and never auto-commits. + +Treat an applied fix like any other code change: read the diff, and run the actual Cypress spec that uses the selector before trusting it — restoring the token proves the selector *resolves* again, not that the underlying behavior is correct. + +## As a Claude Code skill + +`applications/Unity.AutoUI/.claude/skills/validate-cypress-selectors/SKILL.md` documents this same system for on-demand use inside a Claude Code session — invoke it by name when working on Cypress selectors, page objects, or Razor/C#/JS markup that backs them. + +## Configuration + +- **`selector-contract.config.json`** (repo root of `Unity.AutoUI`) — `cypressRoots`, `applicationRoots`, and `ownershipRules` (regex patterns + reason strings for what's exempt from the static contract). + +## Files that need to be committed for this to work for everyone + +| File | Why | +|---|---| +| `scripts/selector-contract.mjs` | The scanner/classifier — also exports the functions `selector-diff-report.mjs` reuses. | +| `scripts/selector-diff-report.mjs` | The baseline-diff + fix logic. | +| `selector-contract.config.json` | Scan roots and ownership exemptions. | +| `package.json` | `selectors:report` / `selectors:diff` / `selectors:fix` / `selectors:apply` npm scripts. | +| `.claude/skills/validate-cypress-selectors/SKILL.md` | The on-demand skill definition. | +| `cypress/selectors/registry.json` | **The baseline itself.** Without this committed on `main`, `selectors:diff`/`fix`/`apply` have nothing to compare against and will just print a "no baseline found" message. | +| `cypress/selectors/README.md` | This file. | diff --git a/applications/Unity.AutoUI/cypress/selectors/registry.json b/applications/Unity.AutoUI/cypress/selectors/registry.json new file mode 100644 index 000000000..f2d6b4874 --- /dev/null +++ b/applications/Unity.AutoUI/cypress/selectors/registry.json @@ -0,0 +1,5481 @@ +{ + "schemaVersion": 2, + "mode": "report-only", + "generatedAt": "2026-08-19T20:53:21.994Z", + "summary": { + "total": 360, + "matched": 146, + "missing": 42, + "unverified": 81, + "exempt": 91, + "syntax": { + "css": 360, + "xpath": 0 + } + }, + "entries": [ + { + "selector": ".application-details-breadcrumb .application-status", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:67" + ], + "applicationMatches": [] + }, + { + "selector": ".card-header", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:293", + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:303", + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:313" + ], + "applicationMatches": [] + }, + { + "selector": ".checkbox-select", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:58", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:225", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:60", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:440" + ], + "applicationMatches": [] + }, + { + "selector": ".checkbox-select.chkbox", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:81" + ], + "applicationMatches": [] + }, + { + "selector": ".choices__item--selectable", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:369" + ], + "applicationMatches": [] + }, + { + "selector": ".display-input", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:72", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:75", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:76", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:77", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:78", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:79", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:80", + "applications/Unity.AutoUI/cypress/pages/BasePage.ts:139" + ], + "applicationMatches": [] + }, + { + "selector": ".display-input-label", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:246", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:257" + ], + "applicationMatches": [] + }, + { + "selector": ".dt-scroll-body", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:47" + ], + "applicationMatches": [] + }, + { + "selector": ".dt-scroll-body tbody tr", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:48" + ], + "applicationMatches": [] + }, + { + "selector": ".dt-scroll-head", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:49" + ], + "applicationMatches": [] + }, + { + "selector": ".dt-scroll-head span.dt-column-title", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:50", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:893" + ], + "applicationMatches": [] + }, + { + "selector": ".login-pf-page", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:19" + ], + "applicationMatches": [] + }, + { + "selector": ".modal-backdrop", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:446", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:62", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:166", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:251", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:292" + ], + "applicationMatches": [] + }, + { + "selector": ".modal-content", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:418" + ], + "applicationMatches": [] + }, + { + "selector": ".modal-footer", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:438", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:454" + ], + "applicationMatches": [] + }, + { + "selector": ".modal-footer button", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:404" + ], + "applicationMatches": [] + }, + { + "selector": ".modal-title", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:419", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:376", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:409", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:445", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:471" + ], + "applicationMatches": [] + }, + { + "selector": ".modal.show", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:117", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:119", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:89", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:642", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:67", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:165", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:241", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:279", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:291" + ], + "applicationMatches": [] + }, + { + "selector": ".modal.show .btn-close", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:650", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:651" + ], + "applicationMatches": [] + }, + { + "selector": ".modal.show .btn-close, .modal.show [data-bs-dismiss='modal'], .modal.show button.close", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:284" + ], + "applicationMatches": [] + }, + { + "selector": ".modal.show .modal-content", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:248" + ], + "applicationMatches": [] + }, + { + "selector": ".modal.show .modal-content:contains('Confirm Action')", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:238" + ], + "applicationMatches": [] + }, + { + "selector": ".modal.show button", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:641" + ], + "applicationMatches": [] + }, + { + "selector": ".modal.show, .modal.fade.show", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:443" + ], + "applicationMatches": [] + }, + { + "selector": ".right-card", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:13" + ], + "applicationMatches": [] + }, + { + "selector": ".select-all-applications", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:80" + ], + "applicationMatches": [] + }, + { + "selector": ".select2-dropdown", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:17" + ], + "applicationMatches": [] + }, + { + "selector": ".submission-attachments-table, [id*='SubmissionAttachments']", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:93" + ], + "applicationMatches": [] + }, + { + "selector": ".summary-table", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:48" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-close", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:189", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:190" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-confirm", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:105", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:106", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:191", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:192", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:638" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-container", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:101", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:187", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:188", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:197", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:90", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:96", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:98", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:637", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:652", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:68", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:164", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:233", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:276" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-container .swal2-confirm", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:636", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:272", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:273" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-container .swal2-icon.swal2-error", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:630" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-container button", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:110" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-popup", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:236", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:39" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-popup .swal2-confirm", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:229", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:230" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-popup button", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:237", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:243" + ], + "applicationMatches": [] + }, + { + "selector": ".swal2-popup, .modal.show", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:46" + ], + "applicationMatches": [] + }, + { + "selector": ".tags-suggestion-container .tags-suggestion-element", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:391", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:394" + ], + "applicationMatches": [] + }, + { + "selector": ".unity-user-initials", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:73", + "applications/Unity.AutoUI/cypress/pages/LoginPage.ts:15", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:16", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:30", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:37" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"1\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:357" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"10\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:363" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"11\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:364" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"12\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:365" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"15\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:366" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"2\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:358" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"3\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:359" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"31\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:367" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"32\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:368" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"4\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:360" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"5\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:361" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"63\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:369" + ], + "applicationMatches": [] + }, + { + "selector": "[data-dt-column=\"9\"] .dt-column-order", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:362" + ], + "applicationMatches": [] + }, + { + "selector": "[role=\"combobox\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:22" + ], + "applicationMatches": [] + }, + { + "selector": "#${fieldId}", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:313" + ], + "applicationMatches": [] + }, + { + "selector": "#addLinkBtn", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:addLinkBtn" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:102" + ], + "applicationMatches": [] + }, + { + "selector": "#AdjudicationTeamLeadActionBar #CompleteButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:CompleteButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:63" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#app > div > main > div.v-container.v-locale--is-ltr.text-center.main > div > div:nth-child(2) > div > button", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/commands.ts:169", + "applications/Unity.AutoUI/cypress/support/commands.ts:173" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/BulkApprovals/ApproveApplicationsModal.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantAttachments/ApplicantAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantPayments/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantsActionBar/ListMerge.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/DetailsActionBar/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/PaymentConfiguration/Default.js" + ] + }, + { + "selector": "#app > div > main > header > header > div > div.d-print-none", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/commands.ts:154", + "applications/Unity.AutoUI/cypress/support/commands.ts:157" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/BulkApprovals/ApproveApplicationsModal.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantAttachments/ApplicantAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantPayments/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantsActionBar/ListMerge.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/DetailsActionBar/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/PaymentConfiguration/Default.js" + ] + }, + { + "selector": "#app_custom_buttons", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:38" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentActionBar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ConfigurationManagement/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantPrograms/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Intakes/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/PaymentHistory/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantsActionBar/Default.cshtml" + ] + }, + { + "selector": "#ApplicantInfo_MailingAddressCity", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_MailingAddressCity" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:94" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_MailingAddressPostalCode", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_MailingAddressPostalCode" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:96" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_MailingAddressProvince", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_MailingAddressProvince" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:95" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_MailingAddressStreet", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_MailingAddressStreet" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:91" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_MailingAddressStreet2", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_MailingAddressStreet2" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:92" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_MailingAddressUnit", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_MailingAddressUnit" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:93" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_SigningAuthorityBusinessPhone", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_SigningAuthorityBusinessPhone" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:101" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_SigningAuthorityCellPhone", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_SigningAuthorityCellPhone" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:102" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_SigningAuthorityEmail", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_SigningAuthorityEmail" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:99" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_SigningAuthorityFullName", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_SigningAuthorityFullName" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:97" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantInfo_SigningAuthorityTitle", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantInfo_SigningAuthorityTitle" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:98" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_ApplicantName", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:117" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js" + ] + }, + { + "selector": "#ApplicantSummary_ContactBusinessPhone", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_ContactBusinessPhone" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:83" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_ContactCellPhone", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_ContactCellPhone" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:84" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_ContactEmail", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_ContactEmail" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:82" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_ContactFullName", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_ContactFullName" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:80" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_ContactTitle", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_ContactTitle" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:81" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_OrgName", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:78" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/SupplierInfo.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js" + ] + }, + { + "selector": "#ApplicantSummary_OrgNumber", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:79" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js" + ] + }, + { + "selector": "#ApplicantSummary_PhysicalAddressCity", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_PhysicalAddressCity" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:88" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_PhysicalAddressPostalCode", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_PhysicalAddressPostalCode" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:90" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_PhysicalAddressProvince", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_PhysicalAddressProvince" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:89" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_PhysicalAddressStreet", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_PhysicalAddressStreet" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:85" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_PhysicalAddressStreet2", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_PhysicalAddressStreet2" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:86" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_PhysicalAddressUnit", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicantSummary_PhysicalAddressUnit" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:87" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicantSummary_Sector", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:119", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:140" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js" + ] + }, + { + "selector": "#ApplicantSummary_SectorSubSectorIndustryDesc", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:123", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:104" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js" + ] + }, + { + "selector": "#ApplicantSummary_SubSector", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:120", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:169" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js" + ] + }, + { + "selector": "#Application_ApproveButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_ApproveButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:29", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:59" + ], + "applicationMatches": [] + }, + { + "selector": "#application_attachment_count", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:39" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#Application_CloseButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_CloseButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:31" + ], + "applicationMatches": [] + }, + { + "selector": "#application_comments_count", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:38" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CommentsWidget/Default.cshtml" + ] + }, + { + "selector": "#Application_CompleteAssessmentButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_CompleteAssessmentButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:28", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:58" + ], + "applicationMatches": [] + }, + { + "selector": "#Application_CompleteReviewButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_CompleteReviewButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:26", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:56" + ], + "applicationMatches": [] + }, + { + "selector": "#Application_DeferButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_DeferButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:33" + ], + "applicationMatches": [] + }, + { + "selector": "#Application_DenyButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_DenyButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:30" + ], + "applicationMatches": [] + }, + { + "selector": "#application_emails_count", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:37" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml" + ] + }, + { + "selector": "#application_links_count", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:40" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.js" + ] + }, + { + "selector": "#Application_OnHoldButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_OnHoldButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:34" + ], + "applicationMatches": [] + }, + { + "selector": "#Application_StartAssessmentButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_StartAssessmentButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:27", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:57" + ], + "applicationMatches": [] + }, + { + "selector": "#Application_StartReviewButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_StartReviewButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:25", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:55" + ], + "applicationMatches": [] + }, + { + "selector": "#application_upload", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:application_upload" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:95" + ], + "applicationMatches": [] + }, + { + "selector": "#application_upload_btn", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:application_upload_btn" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:94" + ], + "applicationMatches": [] + }, + { + "selector": "#Application_WithdrawButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:Application_WithdrawButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:32" + ], + "applicationMatches": [] + }, + { + "selector": "#ApplicationActionDropdown", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:22" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationActionWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationActionWidget/Default.js" + ] + }, + { + "selector": "#ApplicationActionDropdown .dropdown-menu", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:24", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:54" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationActionWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationActionWidget/Default.js" + ] + }, + { + "selector": "#ApplicationActionDropdown .dropdown-toggle", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:23", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:53" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationActionWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationActionWidget/Default.js" + ] + }, + { + "selector": "#applicationAssigneeChart > div > svg > g > text:nth-child(1)", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:11" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js" + ] + }, + { + "selector": "#ApplicationAttachmentsTable", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:92" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationAttachments/ApplicationAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationAttachments/Default.cshtml" + ] + }, + { + "selector": "#ApplicationCount", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:456" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatus.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatusModal.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequests.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequestsModal.js" + ] + }, + { + "selector": "#ApplicationHistoryTable", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ApplicationHistoryTable" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:107" + ], + "applicationMatches": [] + }, + { + "selector": "#applicationLink", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:66", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:67", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:75", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:91" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.js" + ] + }, + { + "selector": "#ApplicationLinksTable", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:101" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.js" + ] + }, + { + "selector": "#applicationPaymentRequest", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:382", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:90" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js" + ] + }, + { + "selector": "#applicationStatusChart > div > svg > g > text:nth-child(1)", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:7" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js" + ] + }, + { + "selector": "#applicationStatusChart text", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:95" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js" + ] + }, + { + "selector": "#applicationStatusWidget", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:45" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#applicationTagsWidget", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:46" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#ApprovalView_ApprovedAmount", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:81", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:340" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.cshtml" + ] + }, + { + "selector": "#ApprovalView_FinalDecisionDate", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:82", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:346" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.js" + ] + }, + { + "selector": "#approveApplications", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:88" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/BulkApprovals/ApproveApplicationsModal.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/DetailsActionBar/Default.js" + ] + }, + { + "selector": "#AssessmentId", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:54" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260721203242_Initial.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260721203242_Initial.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260805212847_AddGenerationReviews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806201536_AB33799_HardenCheckboxGroupReportingViews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806202244_AB33799_FixCheckboxGroupEmptyValues.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260807224046_AB33996_AddApplicantFiscalYearEndRestricted.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260813164219_AB33234_ApplicantPortalExternalLinks.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260818211028_AB33234_ExternalLinksApplicantMessage.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/GrantTenantDbContextModelSnapshot.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResultAttachments/AssessmentResultAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/_Shared/Attachments.js" + ] + }, + { + "selector": "#assessmentMainView", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:87" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#assignApplication", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:87", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:370" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js" + ] + }, + { + "selector": "#AssigneeId", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:380" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260721203242_Initial.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260721203242_Initial.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260805212847_AddGenerationReviews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806201536_AB33799_HardenCheckboxGroupReportingViews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806202244_AB33799_FixCheckboxGroupEmptyValues.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260807224046_AB33996_AddApplicantFiscalYearEndRestricted.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260813164219_AB33234_ApplicantPortalExternalLinks.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260818211028_AB33234_ExternalLinksApplicantMessage.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/GrantTenantDbContextModelSnapshot.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/AssigneeSelection/AssigneeSelectionModal.cshtml" + ] + }, + { + "selector": "#attachments", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:30", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:573" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Operations/ApplicationAnalysisOperationInputDto.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Operations/ApplicationScoringOperationInputDto.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Requests/ApplicationAnalysisRequest.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Requests/ApplicationScoringRequest.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application/Runtime/Prompts/PromptDataPayloadBuilder.cs", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Application/EmailNotificaions/EmailNotificationManager.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantAttachments/ApplicantAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationAttachments/ApplicationAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ChefsAttachments/ChefsAttachments.js" + ] + }, + { + "selector": "#attachments input[type='file']", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:546" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Operations/ApplicationAnalysisOperationInputDto.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Operations/ApplicationScoringOperationInputDto.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Requests/ApplicationAnalysisRequest.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application.Contracts/Requests/ApplicationScoringRequest.cs", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Application/Runtime/Prompts/PromptDataPayloadBuilder.cs", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Application/EmailNotificaions/EmailNotificationManager.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantAttachments/ApplicantAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationAttachments/ApplicationAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ChefsAttachments/ChefsAttachments.js" + ] + }, + { + "selector": "#attachments-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:20" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantAttachments/ApplicantAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationAttachments/ApplicationAttachments.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ChefsAttachments/ChefsAttachments.js" + ] + }, + { + "selector": "#bcc-input-row", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:288" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#bs-select-1[role=\"listbox\"]", + "kind": "id", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [ + "id:bs-select-1" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:18" + ], + "applicationMatches": [] + }, + { + "selector": "#btn-cancel-email", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:78" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#btn-confirm-send", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:127", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:140", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:91", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:79", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:161" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#btn-new-email", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:215", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:67", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:116" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#btn-save", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:76", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:135" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Views/Shared/Components/AIConfiguration/Default.js", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Web/Views/Shared/Components/ReportingConfiguration/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/FormConfiguration/Notifications.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Template/Template.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/Notifications/Notifications.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/PaymentConfiguration/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/wwwroot/js/formConfiguration/Notifications.js" + ] + }, + { + "selector": "#btn-save-top, #btn-save", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:316", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:340" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Views/Shared/Components/AIConfiguration/Default.js", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Web/Views/Shared/Components/ReportingConfiguration/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/FormConfiguration/Notifications.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Template/Template.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/Notifications/Notifications.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/PaymentConfiguration/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/wwwroot/js/formConfiguration/Notifications.js" + ] + }, + { + "selector": "#btn-send", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:77", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:154" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#btn-send-top, #btn-send", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:339", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:346" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#btn-show-bcc", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:290" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#btn-toggle-filter", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:92" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/Index.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Onboarding/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Onboarding/Index.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Reconciliation/Index.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js", + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/plugins/filterRow.js", + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/plugins/tableContextMenu.js", + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/table-utils.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantSubmissions/Default.js" + ] + }, + { + "selector": "#btnSubmitPayment", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:466" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatus.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatusModal.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequests.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequestsModal.js" + ] + }, + { + "selector": "#cleanGrowth", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:58" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#closeSummaryCanvas", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:82", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:77" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml" + ] + }, + { + "selector": "#comments", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:29" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Flex/test/Unity.Flex.Application.Tests/Reporting/ScoresheetFieldSchemaParserTests.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#comments .add-comment-cancel-button", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:86" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Flex/test/Unity.Flex.Application.Tests/Reporting/ScoresheetFieldSchemaParserTests.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#comments .add-comment-save-button", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:85" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Flex/test/Unity.Flex.Application.Tests/Reporting/ScoresheetFieldSchemaParserTests.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#comments .comment-input", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:84" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Flex/test/Unity.Flex.Application.Tests/Reporting/ScoresheetFieldSchemaParserTests.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#comments .comments-container", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:87" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Flex/test/Unity.Flex.Application.Tests/Reporting/ScoresheetFieldSchemaParserTests.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#comments-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:19" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#communities", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:104", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:69" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.js" + ] + }, + { + "selector": "#CompleteButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:CompleteButton" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:86" + ], + "applicationMatches": [] + }, + { + "selector": "#ContactInfo_Email", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:135" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml" + ] + }, + { + "selector": "#ContactInfo_Name", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:133" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml" + ] + }, + { + "selector": "#ContactInfo_Phone", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:ContactInfo_Phone" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:136" + ], + "applicationMatches": [] + }, + { + "selector": "#ContactInfo_Phone2", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:137" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml" + ] + }, + { + "selector": "#ContactInfo_Title", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:134" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml" + ] + }, + { + "selector": "#CreateButton", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:85", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:611", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:612" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ConfigurationManagement/PaymentConfigurations.js" + ] + }, + { + "selector": "#details", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:27" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Application/GrantsPortal/Messages/MessageAcknowledgment.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#details-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:17" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#detailsTabContent", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:14" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js" + ] + }, + { + "selector": "#dynamicButtonContainerId", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:39" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/Prompts/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/Prompts/Index.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/index.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/index.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentActionBar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.js" + ] + }, + { + "selector": "#dynamicButtonContainerId .dt-buttons button, #dynamicButtonContainerId .dt-buttons button span", + "kind": "id", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:41", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:419", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:604" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/Prompts/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/Prompts/Index.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/index.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/index.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentActionBar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.js" + ] + }, + { + "selector": "#dynamicButtonContainerId button.grp-savedStates", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:407" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/Prompts/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/Prompts/Index.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/index.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/index.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentActionBar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.js" + ] + }, + { + "selector": "#economicImpact", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:56" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#economicRegionChart > div > svg > g > text:nth-child(1)", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:9" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js" + ] + }, + { + "selector": "#economicRegions", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:102", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:67" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.js" + ] + }, + { + "selector": "#EmailBCC", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:294", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:299", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:336", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:72", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:132", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:151" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#EmailBody", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:252", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:75" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#EmailCC", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:275", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:280", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:335", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:71", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:131", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:150" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#EmailForm", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:332", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:68" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#EmailFrom", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:73" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#EmailHistoryTable", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:68", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:70" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/Default.js" + ] + }, + { + "selector": "#EmailHistoryTable td", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:321" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/Default.js" + ] + }, + { + "selector": "#emails", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:28", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:141" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/Default.js" + ] + }, + { + "selector": "#emails-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:203", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:207", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:18", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:107" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/Default.js" + ] + }, + { + "selector": "#EmailSubject", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:305", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:310", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:337", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:74", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:133", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:152" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#EmailTo", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:219", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:264", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:269", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:334", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:70", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:130", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:149" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#externalLink", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:85", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:235", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:76", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:86" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js" + ] + }, + { + "selector": "#financialAnalysis", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:55" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#formio", + "kind": "id", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:17" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#GrantApplicationsTable", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:79", + "applications/Unity.AutoUI/cypress/support/auth.ts:31" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js" + ] + }, + { + "selector": "#GrantApplicationsTable tbody", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:82" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js" + ] + }, + { + "selector": "#GrantApplicationsTable tbody a[href^=\"/GrantApplications/Details?ApplicationId=\"]", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:172", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:177" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js" + ] + }, + { + "selector": "#GrantApplicationsTable tbody a[href^=\"/GrantApplications/Details\"]", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:98" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js" + ] + }, + { + "selector": "#GrantApplicationsTable tbody tr", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:83" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js" + ] + }, + { + "selector": "#GrantApplicationsTable tbody tr td a", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:84" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js" + ] + }, + { + "selector": "#history", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:32" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/HistoryWidget/Default.js" + ] + }, + { + "selector": "#history-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:22" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/HistoryWidget/Default.js" + ] + }, + { + "selector": "#inclusiveGrowth", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:57" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#links", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:31" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Application/Configuration/FieldsProviders/WorksheetFieldsProvider.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicationLinksWidget/Default.js" + ] + }, + { + "selector": "#links-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:21" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#main-left", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:666" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Applicants/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#modal-content", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:158" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/InternalEmailGroups.js", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Web/Views/Shared/Components/ReportingConfiguration/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Web/Views/Shared/Components/ReportingConfigurationViewStatus/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Onboarding/Index.js", + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/json-editor.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantsActionBar/ListMerge.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#nav-funding-agreement-info-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:nav-funding-agreement-info-tab" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:16" + ], + "applicationMatches": [] + }, + { + "selector": "#nav-organization-info-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:15" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/SupplierInfo.js" + ] + }, + { + "selector": "#nav-payment-info-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:175", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:17", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:155" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.js" + ] + }, + { + "selector": "#nav-project-info-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:nav-project-info-tab" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:93", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:14" + ], + "applicationMatches": [] + }, + { + "selector": "#nav-review-and-assessment", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:16" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#nav-review-and-assessment-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:88", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:13" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#nav-summery", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:15" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml" + ] + }, + { + "selector": "#nav-summery-tab", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "missing", + "missingTokens": [ + "id:nav-summery-tab" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:179", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:12" + ], + "applicationMatches": [] + }, + { + "selector": "#Note", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:458", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:464" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatus.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260721203242_Initial.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260805212847_AddGenerationReviews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806201536_AB33799_HardenCheckboxGroupReportingViews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806202244_AB33799_FixCheckboxGroupEmptyValues.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260807224046_AB33996_AddApplicantFiscalYearEndRestricted.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260813164219_AB33234_ApplicantPortalExternalLinks.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260818211028_AB33234_ExternalLinksApplicantMessage.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/GrantTenantDbContextModelSnapshot.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicantHistory/ReportsHistoryModalViewModel.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantHistory/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/PaymentConfiguration/Default.js" + ] + }, + { + "selector": "#password", + "kind": "id", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/LoginPage.ts:13", + "applications/Unity.AutoUI/cypress/support/commands.ts:185", + "applications/Unity.AutoUI/cypress/support/commands.ts:24" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Application/Configuration/FormsIoMappingUtils.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/TokenModal.js" + ] + }, + { + "selector": "#password, input[name='password'], input[type='password']", + "kind": "id", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:45" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Application/Configuration/FormsIoMappingUtils.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/TokenModal.js" + ] + }, + { + "selector": "#payment-modal", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:61" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatus.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatusModal.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequests.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequestsModal.js" + ] + }, + { + "selector": "#payment-modal .modal-footer button", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:63" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatus.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatusModal.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequests.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequestsModal.js" + ] + }, + { + "selector": "#payment-modal input[id$='__Description']", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:820" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatus.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatusModal.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequests.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/CreatePaymentRequestsModal.js" + ] + }, + { + "selector": "#ProjectInfo_Acquisition", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:99", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:64" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#ProjectInfo_CommunityPopulation", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:105", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:70" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#ProjectInfo_ElectoralDistrict", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:106", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:71" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#ProjectInfo_Forestry", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:100", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:65" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#ProjectInfo_ForestryFocus", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:101", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:66" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#ProjectInfo_Place", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:107", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:72" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#ProjectInfo_ProjectEndDate", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:96", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:61" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#ProjectInfo_ProjectName", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:94", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:59" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml" + ] + }, + { + "selector": "#recommendation_reset_btn", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:62" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#recommendation_select", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:61" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#regionalDistricts", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:103", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:68" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.js" + ] + }, + { + "selector": "#RequestedAmount", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:176" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Application/TenantManagement/OnboardingCoreFieldRegistry.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260721203242_Initial.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260805212847_AddGenerationReviews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806201536_AB33799_HardenCheckboxGroupReportingViews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806202244_AB33799_FixCheckboxGroupEmptyValues.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260807224046_AB33996_AddApplicantFiscalYearEndRestricted.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260813164219_AB33234_ApplicantPortalExternalLinks.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260818211028_AB33234_ExternalLinksApplicantMessage.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/GrantTenantDbContextModelSnapshot.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantSubmissions/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.js" + ] + }, + { + "selector": "#RequestedAmountInputAR", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:89" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.js" + ] + }, + { + "selector": "#RequestedAmountInputPI", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:97", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:62" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.js" + ] + }, + { + "selector": "#reviewDetails", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:53" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js" + ] + }, + { + "selector": "#saveAssessmentScoresBtn", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:60" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js" + ] + }, + { + "selector": "#savePaymentInfoBtn", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:347" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.js" + ] + }, + { + "selector": "#search", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:33", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:45", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:46", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:50", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:211", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:46", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:877", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:89" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/Prompts/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Views/Shared/Components/AIPromptsWidget/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Flex/src/Unity.Flex.Web/Views/Shared/Components/DataGridWidget/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Roles/PermissionRoleMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.cshtml", + "applications/Unity.GrantManager/modules/Unity.Identity.Web/src/Pages/Identity/Users/PermissionUserMatrix.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentConfigurations/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentActionBar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Web/Views/Shared/Components/ReportingConfiguration/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/EndpointManagement/Endpoints/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Onboarding/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Onboarding/Index.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Reconciliation/Index.js", + "applications/Unity.GrantManager/modules/Unity.TenantManagement/src/Unity.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml" + ] + }, + { + "selector": "#search-grant-programs", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:75", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:79", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:55" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantPrograms/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantPrograms/Index.js" + ] + }, + { + "selector": "#select2-dashboardIntakeId-container", + "kind": "id", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [ + "id:select2-dashboardIntakeId-container" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:16" + ], + "applicationMatches": [] + }, + { + "selector": "#Site_PaymentGroup", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:428" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/SupplierInfo.js" + ] + }, + { + "selector": "#SiteInfoTable", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:664", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:665" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/SupplierInfo.js" + ] + }, + { + "selector": "#SiteInfoTable tbody tr", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:380", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:391", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:405", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:675" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/SupplierInfo.js" + ] + }, + { + "selector": "#social-azureidir", + "kind": "id", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [ + "id:social-azureidir" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:21", + "applications/Unity.AutoUI/cypress/support/auth.ts:96", + "applications/Unity.AutoUI/cypress/support/auth.ts:98" + ], + "applicationMatches": [] + }, + { + "selector": "#social-idir", + "kind": "id", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [ + "id:social-idir" + ], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:157", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:158", + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:64", + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:65", + "applications/Unity.AutoUI/cypress/support/auth.ts:101", + "applications/Unity.AutoUI/cypress/support/auth.ts:20", + "applications/Unity.AutoUI/cypress/support/auth.ts:99", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:89", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:90" + ], + "applicationMatches": [] + }, + { + "selector": "#startDate", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:95", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:60" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Intakes/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#subsectorRequestedAmountChart > div > svg > g > text:nth-child(1)", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:13" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js" + ] + }, + { + "selector": "#subTotal", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:59" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentScoresWidget/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ReviewList/ReviewList.js" + ] + }, + { + "selector": "#summaryWidgetArea", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:47" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js" + ] + }, + { + "selector": "#SupplierNumber", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:327" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentInfo/Default.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/SupplierInfo/SupplierInfo.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260721203242_Initial.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260805212847_AddGenerationReviews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806201536_AB33799_HardenCheckboxGroupReportingViews.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260806202244_AB33799_FixCheckboxGroupEmptyValues.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260807224046_AB33996_AddApplicantFiscalYearEndRestricted.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260813164219_AB33234_ApplicantPortalExternalLinks.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260818211028_AB33234_ExternalLinksApplicantMessage.Designer.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/GrantTenantDbContextModelSnapshot.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ApplicantInfo/Default.js" + ] + }, + { + "selector": "#tagApplication", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:89" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationTags/ApplicationTags.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/DetailsActionBar/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/DetailsActionBar/Default.js" + ] + }, + { + "selector": "#template", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:69", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:124" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Flex/src/Unity.Flex.Web/Views/Shared/Components/Scoresheet/Scoresheet.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Zones/ZoneManager.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Template/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "#TotalBudgetInputAR", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:90" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/AssessmentResults/Default.js" + ] + }, + { + "selector": "#TotalBudgetInputPI", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:98", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:63" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ProjectInfo/Default.js" + ] + }, + { + "selector": "#UpdateTotalAmount", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:457" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatus.cshtml", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentApprovals/UpdatePaymentRequestStatusModal.js" + ] + }, + { + "selector": "#user", + "kind": "id", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/LoginPage.ts:12", + "applications/Unity.AutoUI/cypress/support/commands.ts:182", + "applications/Unity.AutoUI/cypress/support/commands.ts:184", + "applications/Unity.AutoUI/cypress/support/commands.ts:21", + "applications/Unity.AutoUI/cypress/support/commands.ts:23" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/InternalEmailGroups.js", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Application/Configuration/ReportMappingUtils.cs", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Web/Views/Shared/Components/ReportingConfiguration/Default.js", + "applications/Unity.GrantManager/modules/Unity.Reporting/test/Unity.Reporting.Application.Tests/Configuration/ColumnsMappingServiceTests.cs" + ] + }, + { + "selector": "#user-dropdown .btn-dropdown span", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/LoginPage.ts:16", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:17" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Components/Topbar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/layout.js" + ] + }, + { + "selector": "#user-dropdown a.dropdown-item", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:74", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:58", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:40" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Components/Topbar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/layout.js" + ] + }, + { + "selector": "#user-tags-input", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:384", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:400" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/AssigneeSelection/AssigneeSelection.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.js" + ] + }, + { + "selector": "#user, input[name='user'], input[name='username']", + "kind": "id", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:44" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/InternalEmailGroups.js", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Application/Configuration/ReportMappingUtils.cs", + "applications/Unity.GrantManager/modules/Unity.Reporting/src/Unity.Reporting.Web/Views/Shared/Components/ReportingConfiguration/Default.js", + "applications/Unity.GrantManager/modules/Unity.Reporting/test/Unity.Reporting.Application.Tests/Configuration/ColumnsMappingServiceTests.cs" + ] + }, + { + "selector": "#UserGrantProgramsTable", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:85", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:60" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantPrograms/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantPrograms/Index.js" + ] + }, + { + "selector": "#UserGrantProgramsTable tbody tr", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:76" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantPrograms/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantPrograms/Index.js" + ] + }, + { + "selector": "a.dropdown-item", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:55", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:82" + ], + "applicationMatches": [] + }, + { + "selector": "a.dropdown-item[role=\"option\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:54", + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:83" + ], + "applicationMatches": [] + }, + { + "selector": "a.nav-link", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:110" + ], + "applicationMatches": [] + }, + { + "selector": "a[id^='social-']", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:106" + ], + "applicationMatches": [] + }, + { + "selector": "body", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:156", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:186", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:194", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:235", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:287", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:45", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:67", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:88", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:95", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:36", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:55", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:65", + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:63", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:339", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:442", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:520", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:526", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:628", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:513", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:477", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:493", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:495", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:499", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:510", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:569", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:673", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:684", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:695", + "applications/Unity.AutoUI/cypress/pages/BasePage.ts:87", + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:106", + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:31", + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:43", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:43", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:55", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:68", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:121", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:210", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:214", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:219", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:258", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:264", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:271", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:289", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:298", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:345", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:389", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:416", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:610", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:642", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:674", + "applications/Unity.AutoUI/cypress/support/auth.ts:117", + "applications/Unity.AutoUI/cypress/support/auth.ts:149", + "applications/Unity.AutoUI/cypress/support/auth.ts:175", + "applications/Unity.AutoUI/cypress/support/auth.ts:203", + "applications/Unity.AutoUI/cypress/support/auth.ts:218", + "applications/Unity.AutoUI/cypress/support/auth.ts:54", + "applications/Unity.AutoUI/cypress/support/auth.ts:94", + "applications/Unity.AutoUI/cypress/support/commands.ts:146", + "applications/Unity.AutoUI/cypress/support/commands.ts:163", + "applications/Unity.AutoUI/cypress/support/commands.ts:180", + "applications/Unity.AutoUI/cypress/support/commands.ts:19", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:27", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:39", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:47", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:88" + ], + "applicationMatches": [] + }, + { + "selector": "button", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:132", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:52", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:367", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:439", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:455", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:643", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:718", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:91", + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:415", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:244", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:442", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:825", + "applications/Unity.AutoUI/cypress/support/auth.ts:151", + "applications/Unity.AutoUI/cypress/support/auth.ts:178", + "applications/Unity.AutoUI/cypress/support/auth.ts:213", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:66" + ], + "applicationMatches": [] + }, + { + "selector": "button, a", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:407", + "applications/Unity.AutoUI/cypress/support/commands.ts:149", + "applications/Unity.AutoUI/cypress/support/commands.ts:166" + ], + "applicationMatches": [] + }, + { + "selector": "button, a, [role='button']", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/library/chefs.cy.ts:11", + "applications/Unity.AutoUI/cypress/e2e/library/chefs.cy.ts:12", + "applications/Unity.AutoUI/cypress/e2e/library/chefs.cy.ts:6" + ], + "applicationMatches": [] + }, + { + "selector": "button:contains('Add Attachments'), .add-attachments-btn, [id*='addAttachment']", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:96" + ], + "applicationMatches": [] + }, + { + "selector": "button:contains('IDIR'), a:contains('IDIR')", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/commands.ts:165" + ], + "applicationMatches": [] + }, + { + "selector": "button:contains('LOGIN'), a:contains('LOGIN')", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/commands.ts:148" + ], + "applicationMatches": [] + }, + { + "selector": "button:contains(\"Continue\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:150" + ], + "applicationMatches": [] + }, + { + "selector": "button:contains(\"LOGIN\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:39", + "applications/Unity.AutoUI/cypress/support/commands.ts:49" + ], + "applicationMatches": [] + }, + { + "selector": "button:contains(\"Save\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:83" + ], + "applicationMatches": [] + }, + { + "selector": "button:contains(\"VIEW APPLICATIONS\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:176", + "applications/Unity.AutoUI/cypress/support/auth.ts:30", + "applications/Unity.AutoUI/cypress/support/auth.ts:50" + ], + "applicationMatches": [] + }, + { + "selector": "button:not([disabled])", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:739" + ], + "applicationMatches": [] + }, + { + "selector": "button.grp-savedStates", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:42", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:81" + ], + "applicationMatches": [] + }, + { + "selector": "button.swal2-cancel", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:41" + ], + "applicationMatches": [] + }, + { + "selector": "button.swal2-confirm", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:40" + ], + "applicationMatches": [] + }, + { + "selector": "button[data-id=\"dashboardIntakeId\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:17" + ], + "applicationMatches": [] + }, + { + "selector": "button[type='submit']", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:154", + "applications/Unity.AutoUI/cypress/support/auth.ts:155" + ], + "applicationMatches": [] + }, + { + "selector": "div.display-input", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:73", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:74" + ], + "applicationMatches": [] + }, + { + "selector": "div.dt-button-background", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:56" + ], + "applicationMatches": [] + }, + { + "selector": "div.spinner-grow[role=\"status\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:22" + ], + "applicationMatches": [] + }, + { + "selector": "fieldset[name=\"Unity_GrantManager_ApplicationManagement_Applicant_Contact\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:129" + ], + "applicationMatches": [] + }, + { + "selector": "fieldset[name=\"Unity_GrantManager_ApplicationManagement_Applicant_Summary\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:113" + ], + "applicationMatches": [] + }, + { + "selector": "fieldset[name$=\"Applicant_Summary\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:77" + ], + "applicationMatches": [] + }, + { + "selector": "form", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:158" + ], + "applicationMatches": [] + }, + { + "selector": "h4", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:194", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:197", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:296" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:109", + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:146" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title:contains(\"1. INTRODUCTION\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:22" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title:contains(\"2. ELIGIBILITY\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:23" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title:contains(\"3. APPLICANT INFORMATION\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:24" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title:contains(\"4. PROJECT INFORMATION\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:25" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title:contains(\"5. PROJECT TIMELINES\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:26" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title:contains(\"6. PROJECT BUDGET\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:27" + ], + "applicationMatches": [] + }, + { + "selector": "h4.card-title:contains(\"7. ATTESTATION\")", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:28" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_ApplicantName]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:33" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_ContactEmail]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:49" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_ContactName]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:47" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_ContactPhoneNumberPrimary]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:50" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_ContactPhoneNumberSecondary]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:51" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_ContactTitle]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:48" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_dateExtractBusinessName]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:34" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_MailingAddressCity]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:59" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_MailingAddressPostalCode]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:61" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_MailingAddressStreet1]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:57" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_MailingAddressStreet2]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:58" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_MailingAddressUnit]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:56" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_OrganizationName]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:36" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_ProjectName]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:66" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_registeredBusinessNumber]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:35" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_RequestedAmount]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:75" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[_TotalProjectBudget]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:76" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"data[${fieldName}]\"]", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:349", + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:358" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"password\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/commands.ts:115" + ], + "applicationMatches": [] + }, + { + "selector": "input[name=\"username\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/commands.ts:109" + ], + "applicationMatches": [] + }, + { + "selector": "input[type='file']", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:531" + ], + "applicationMatches": [] + }, + { + "selector": "input[type='submit']", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/support/auth.ts:152", + "applications/Unity.AutoUI/cypress/support/auth.ts:153" + ], + "applicationMatches": [] + }, + { + "selector": "input[type=\"search\"][aria-controls=\"bs-select-1\"][aria-label=\"Search\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/DashboardPage.ts:20" + ], + "applicationMatches": [] + }, + { + "selector": "input#submittedFromDate", + "kind": "id", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:20" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml" + ] + }, + { + "selector": "input#submittedToDate", + "kind": "id", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:21" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml" + ] + }, + { + "selector": "label", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:304" + ], + "applicationMatches": [] + }, + { + "selector": "label:contains('${labelText}'):visible", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:299" + ], + "applicationMatches": [] + }, + { + "selector": "label.display-input-label[for=\"OrganizationName\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:73" + ], + "applicationMatches": [] + }, + { + "selector": "label.display-input-label[for=\"OrganizationNumber\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:74" + ], + "applicationMatches": [] + }, + { + "selector": "label.form-label", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:105", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:106" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"${labelFor}\"]", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/BasePage.ts:138" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"Category\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:72" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"Community\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:77" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"EconomicRegion\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:75" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"ProjectBudget\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:79" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"RegionalDistrict\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:76" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"RequestedAmount\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:78" + ], + "applicationMatches": [] + }, + { + "selector": "label[for=\"Sector\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:80" + ], + "applicationMatches": [] + }, + { + "selector": "option", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:320" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[_Community]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:70" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[_EconomicRegion]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:68" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[_MailingAddressProvince]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:60" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[_OrganizationType]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:37" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[_OrgBookStatus]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:38" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[_RegionalDistrict]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:69" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[_riskRanking]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:39" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[${fieldName}]\"]", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:367" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[sector]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:40" + ], + "applicationMatches": [] + }, + { + "selector": "select[name=\"data[subsector]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:41" + ], + "applicationMatches": [] + }, + { + "selector": "select[title=\"Select a template to apply\"], #template", + "kind": "id", + "syntaxKind": "css", + "ownership": "application", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:227" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Flex/src/Unity.Flex.Web/Views/Shared/Components/Scoresheet/Scoresheet.js", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Zones/ZoneManager.cs", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Template/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js" + ] + }, + { + "selector": "select#dashboardIntakeId option:selected", + "kind": "id", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:44" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js" + ] + }, + { + "selector": "select#quickDateRange", + "kind": "id", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "matched", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:37", + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:38", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:19" + ], + "applicationMatches": [ + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.cshtml", + "applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/Notifications/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Pages/PaymentRequests/Index.js", + "applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Web/Views/Shared/Components/PaymentActionBar/Default.cshtml", + "applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/plugins/filterRow.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.cshtml", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/UnityAdmin/Index.js", + "applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml" + ] + }, + { + "selector": "tbody tr", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:80", + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:83", + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:86", + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:89", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:564", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:595", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsRightTabPage.ts:607", + "applications/Unity.AutoUI/cypress/pages/BasePage.ts:110", + "applications/Unity.AutoUI/cypress/pages/BasePage.ts:117", + "applications/Unity.AutoUI/cypress/pages/NavigationPage.ts:88", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:144", + "applications/Unity.AutoUI/cypress_manyEmails/manyEmails.cy.ts:63" + ], + "applicationMatches": [] + }, + { + "selector": "td", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:74", + "applications/Unity.AutoUI/cypress/e2e/basicEmail.cy.ts:81", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:394", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:395", + "applications/Unity.AutoUI/cypress/pages/ApplicationDetailsPage.ts:396", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:269", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:899" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.applicantId + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:345" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.applicantName + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:297", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:405", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:507", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:559" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.approvedAmount + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:329", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:439" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.assignee + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:317", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:474" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.category + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:305", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:529" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.community + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:333" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.projectName + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:313" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.requestedAmount + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:325", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:430", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:543" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.status + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:321", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:386", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:399", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:452", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:515" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.submissionDate + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:309" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.submissionNumber + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:301", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:409", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:511" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.subStatus + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:337", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:492" + ], + "applicationMatches": [] + }, + { + "selector": "td:nth-child(${this.columns.tags + 1})", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:341", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:483" + ], + "applicationMatches": [] + }, + { + "selector": "textarea.select2-search__field", + "kind": "css", + "syntaxKind": "css", + "ownership": "framework-generated", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/lists.cy.ts:30" + ], + "applicationMatches": [] + }, + { + "selector": "textarea[name=\"data[_OtherSubSector]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:42" + ], + "applicationMatches": [] + }, + { + "selector": "textarea[name=\"data[_ProjectDescription]\"]", + "kind": "css", + "syntaxKind": "css", + "ownership": "external", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/pages/ReviewAssessmentPage.ts:67" + ], + "applicationMatches": [] + }, + { + "selector": "th", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:895" + ], + "applicationMatches": [] + }, + { + "selector": "tr", + "kind": "css", + "syntaxKind": "css", + "ownership": "unclassified", + "status": "unverified", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:57", + "applications/Unity.AutoUI/cypress/pages/ApplicationsListPage.ts:223", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:53", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:60", + "applications/Unity.AutoUI/cypress/pages/ListPages.ts:66", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:438", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:801", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:882", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:898", + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:93" + ], + "applicationMatches": [] + }, + { + "selector": "tr:contains(\"${id}\")", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/e2e/chefsdata.cy.ts:56" + ], + "applicationMatches": [] + }, + { + "selector": "tr:contains(\"${submissionId}\")", + "kind": "dynamic", + "syntaxKind": "css", + "ownership": "dynamic", + "status": "exempt", + "missingTokens": [], + "usedBy": [ + "applications/Unity.AutoUI/cypress/regression/ApprovalFlow.cy.ts:122" + ], + "applicationMatches": [] + } + ] +} diff --git a/applications/Unity.AutoUI/package.json b/applications/Unity.AutoUI/package.json index 9ec62d2b5..bec021ee0 100644 --- a/applications/Unity.AutoUI/package.json +++ b/applications/Unity.AutoUI/package.json @@ -1,5 +1,9 @@ { "scripts": { + "selectors:report": "node scripts/selector-contract.mjs", + "selectors:diff": "node scripts/selector-diff-report.mjs", + "selectors:fix": "node scripts/selector-diff-report.mjs --fix", + "selectors:apply": "node scripts/selector-diff-report.mjs --apply", "test": "node ./scripts/run-cypress.js run --spec \"cypress/e2e/**/*.cy.ts\" --browser chrome", "test:e2e": "node ./scripts/run-cypress.js run --spec \"cypress/e2e/**/*.cy.ts\" --browser chrome", "test:regression-headed": "node ./scripts/run-cypress.js run --spec \"cypress/regression/**/*.cy.ts\" --headed --browser chrome", diff --git a/applications/Unity.AutoUI/scripts/selector-contract.mjs b/applications/Unity.AutoUI/scripts/selector-contract.mjs new file mode 100644 index 000000000..95203c8c2 --- /dev/null +++ b/applications/Unity.AutoUI/scripts/selector-contract.mjs @@ -0,0 +1,237 @@ +#!/usr/bin/env node + +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { execFileSync } from "node:child_process"; +import ts from "typescript"; + +export const autoUiRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +export const repoRoot = path.resolve(autoUiRoot, "../.."); +export const configPath = path.join(autoUiRoot, "selector-contract.config.json"); +export const registryPath = path.join(autoUiRoot, "cypress/selectors/registry.json"); +const excludedDirectories = new Set(["node_modules", "bin", "obj", ".git", "coverage"]); + +// XPath expressions start with a path axis (`/`, `//`, `./`) or use named +// axis syntax (`ancestor::`, `following-sibling::`, ...) or the `contains()` +// function form — none of which are valid CSS selector syntax. Selectors +// passed to `cy.xpath(...)` (the cypress-xpath plugin command) are also +// treated as XPath regardless of their text shape. +const XPATH_PATTERN = + /^\.{0,2}\/\/|^\/[a-zA-Z*@]|::(?:ancestor|descendant|following-sibling|preceding-sibling|parent|self|child)(?:-or-self)?\b|contains\(\s*(?:text\(\)|@)/; + +export function loadConfig() { + return JSON.parse(fs.readFileSync(configPath, "utf8")); +} + +export function walk(root, extensions) { + const results = []; + if (!fs.existsSync(root)) return results; + for (const entry of fs.readdirSync(root, { withFileTypes: true })) { + const fullPath = path.join(root, entry.name); + if (entry.isDirectory()) { + if (!excludedDirectories.has(entry.name) && !fullPath.includes(`${path.sep}wwwroot${path.sep}libs${path.sep}`)) { + results.push(...walk(fullPath, extensions)); + } + } else if (extensions.has(path.extname(entry.name).toLowerCase())) { + results.push(fullPath); + } + } + return results; +} + +// Only scan files git actually tracks — a raw filesystem walk would also +// pick up local scratch/untracked files (e.g. a spec someone is drafting +// but never committed), which would leak into usedBy/applicationMatches in +// the committed registry and be internally inconsistent for anyone who +// doesn't have those same untracked files sitting on disk. Falls back to +// the plain filesystem walk if git isn't available at all (e.g. a tarball +// checkout with no .git directory). +export function trackedFiles(root, extensions) { + const relRoot = path.relative(repoRoot, root); + try { + const output = execFileSync("git", ["ls-files", "--", relRoot], { + cwd: repoRoot, + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"], + }); + return output + .split("\n") + .filter(Boolean) + .map((tracked) => path.join(repoRoot, tracked)) + .filter((fullPath) => extensions.has(path.extname(fullPath).toLowerCase())) + .filter((fullPath) => !fullPath.includes(`${path.sep}wwwroot${path.sep}libs${path.sep}`)) + .sort(); + } catch { + return walk(root, extensions); + } +} + +function selectorText(node, sourceFile) { + if (ts.isStringLiteralLike(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text.trim(); + if (ts.isTemplateExpression(node)) return node.getText(sourceFile).slice(1, -1).trim(); + return null; +} + +function looksLikeSelector(value) { + if (!value || value.length > 500 || /^(https?:|\/[^\s]+|\{.*\})/.test(value)) return false; + if (XPATH_PATTERN.test(value)) return true; + if (/^[#.\[]/.test(value)) return true; + if (/^(html|body|main|nav|form|label|input|select|option|button|a|table|thead|tbody|tr|td|th|div|span|h[1-6])(?:$|[.#[:\s>+~,])/.test(value)) return true; + return /^[a-z][a-z0-9-]*(?:\[[^\]]+\]|[#.][A-Za-z_-])/.test(value); +} + +function isSelectorPosition(node) { + const parent = node.parent; + if (ts.isPropertyAssignment(parent) || ts.isPropertyDeclaration(parent) || ts.isVariableDeclaration(parent)) return true; + if (!ts.isCallExpression(parent)) return false; + const expression = parent.expression.getText(); + return parent.arguments.indexOf(node) === 0 && /(?:^|\.)(?:get|find|contains|within|closest|filter|children|parents|next|select|getElement|getBySelector|xpath)$/.test(expression); +} + +function callName(node) { + const parent = node.parent; + if (!ts.isCallExpression(parent)) return null; + return parent.expression.getText(); +} + +export function syntaxKind(selector, usedViaXpathCall) { + if (usedViaXpathCall || XPATH_PATTERN.test(selector)) return "xpath"; + return "css"; +} + +export function extractSelectors(config) { + const files = config.cypressRoots + .map((root) => path.join(repoRoot, root)) + .flatMap((root) => trackedFiles(root, new Set([".ts", ".tsx", ".js", ".jsx"]))) + .sort(); + const selectors = new Map(); + for (const file of files) { + const sourceFile = ts.createSourceFile(file, fs.readFileSync(file, "utf8"), ts.ScriptTarget.Latest, true); + function visit(node) { + const value = selectorText(node, sourceFile); + if (value && isSelectorPosition(node) && looksLikeSelector(value)) { + const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)); + const usage = `${path.relative(repoRoot, file).replaceAll(path.sep, "/")}:${position.line + 1}`; + const viaXpathCall = /(?:^|\.)xpath$/.test(callName(node) ?? ""); + if (!selectors.has(value)) { + selectors.set(value, { usages: new Set(), viaXpathCall: false }); + } + const entry = selectors.get(value); + entry.usages.add(usage); + entry.viaXpathCall = entry.viaXpathCall || viaXpathCall; + } + ts.forEachChild(node, visit); + } + visit(sourceFile); + } + return selectors; +} + +function classifyOwnership(selector, ownershipRules) { + const override = ownershipRules.find((rule) => rule.regex.test(selector)); + if (override) return override.ownership; + if (selector.includes("${")) return "dynamic"; + if (/\[data-(?:cy|testid)=/.test(selector) || /(^|[\s>+~,])#[A-Za-z_]/.test(selector)) return "application"; + return "unclassified"; +} + +export function identifyingTokens(selector) { + const tokens = []; + for (const match of selector.matchAll(/#([A-Za-z_][\w:-]*)/g)) tokens.push({ type: "id", value: match[1] }); + for (const match of selector.matchAll(/\[(data-(?:cy|testid))=["']?([^\]"']+)/g)) tokens.push({ type: match[1], value: match[2] }); + return tokens; +} + +// Shared with selector-diff-report.mjs so the "does this token exist in this +// source file" check and the "restore this token to this line" logic use +// the exact same string patterns validate() checks — a fix that satisfies +// buildNeedles() is guaranteed to flip the selector back to "matched". +export function buildNeedles(token) { + const razorModelPath = token.value.replaceAll("_", "."); + return token.type === "id" + ? [ + `id=\"${token.value}\"`, + `id='${token.value}'`, + `Id(\"${token.value}\")`, + `#${token.value}`, + `'${token.value}'`, + `\"${token.value}\"`, + `asp-for=\"@Model.${razorModelPath}\"`, + `asp-for='@Model.${razorModelPath}'` + ] + : [`${token.type}=\"${token.value}\"`, `${token.type}='${token.value}'`]; +} + +export function applicationIndex(config) { + return config.applicationRoots + .map((root) => path.join(repoRoot, root)) + .flatMap((root) => trackedFiles(root, new Set([".cshtml", ".razor", ".html", ".js", ".ts", ".tsx", ".cs"]))) + .sort() + .map((file) => ({ file: path.relative(repoRoot, file).replaceAll(path.sep, "/"), text: fs.readFileSync(file, "utf8") })); +} + +/** + * @param {Map, viaXpathCall: boolean}>} selectors + */ +export function validate(selectors, config, sources) { + const ownershipRules = config.ownershipRules.map((rule) => ({ ...rule, regex: new RegExp(rule.pattern) })); + return [...selectors.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([selector, { usages, viaXpathCall }]) => { + const ownership = classifyOwnership(selector, ownershipRules); + const tokens = identifyingTokens(selector); + const matches = new Set(); + const missingTokens = []; + for (const token of tokens) { + const needles = buildNeedles(token); + const tokenMatches = sources.filter((source) => needles.some((needle) => source.text.includes(needle))); + if (tokenMatches.length === 0) missingTokens.push(`${token.type}:${token.value}`); + tokenMatches.slice(0, 20).forEach((source) => matches.add(source.file)); + } + let status = "unverified"; + if (["external", "framework-generated", "dynamic"].includes(ownership)) status = "exempt"; + else if (tokens.length > 0) status = missingTokens.length === 0 ? "matched" : "missing"; + return { + selector, + kind: selector.includes("${") ? "dynamic" : tokens[0]?.type ?? "css", + syntaxKind: syntaxKind(selector, viaXpathCall), + ownership, + status, + missingTokens, + usedBy: [...usages].sort(), + applicationMatches: [...matches].sort() + }; + }); +} + +export function buildRegistry(config = loadConfig()) { + const entries = validate(extractSelectors(config), config, applicationIndex(config)); + const counts = Object.fromEntries(["matched", "missing", "unverified", "exempt"].map((status) => [status, entries.filter((entry) => entry.status === status).length])); + const syntaxCounts = Object.fromEntries(["css", "xpath"].map((k) => [k, entries.filter((entry) => entry.syntaxKind === k).length])); + return { + schemaVersion: 2, + mode: "report-only", + generatedAt: new Date().toISOString(), + summary: { total: entries.length, ...counts, syntax: syntaxCounts }, + entries + }; +} + +function runCli() { + const config = loadConfig(); + const registry = buildRegistry(config); + fs.mkdirSync(path.dirname(registryPath), { recursive: true }); + fs.writeFileSync(registryPath, `${JSON.stringify(registry, null, 2)}\n`); + console.log(`Cypress selector contract: ${registry.summary.total} selectors`); + for (const status of ["matched", "missing", "unverified", "exempt"]) console.log(` ${status}: ${registry.summary[status]}`); + console.log(` syntax — css: ${registry.summary.syntax.css}, xpath: ${registry.summary.syntax.xpath}`); + for (const entry of registry.entries.filter((candidate) => candidate.status === "missing")) console.log(` MISSING ${entry.selector} (${entry.usedBy.join(", ")})`); + for (const entry of registry.entries.filter((candidate) => candidate.syntaxKind === "xpath")) console.log(` XPATH ${entry.selector} (${entry.usedBy.join(", ")})`); + console.log(`Registry written to ${path.relative(repoRoot, registryPath)}`); +} + +// Only run the CLI report when this file is executed directly +// (`node scripts/selector-contract.mjs`) — not when imported as a module by +// selector-diff-report.mjs. +if (import.meta.url === `file://${process.argv[1]}`) { + runCli(); +} diff --git a/applications/Unity.AutoUI/scripts/selector-diff-report.mjs b/applications/Unity.AutoUI/scripts/selector-diff-report.mjs new file mode 100644 index 000000000..141212552 --- /dev/null +++ b/applications/Unity.AutoUI/scripts/selector-diff-report.mjs @@ -0,0 +1,241 @@ +#!/usr/bin/env node + +// Compares the Cypress selector contract on the current branch/working tree +// against a committed baseline (cypress/selectors/registry.json as it +// exists at --base, default origin/main) to find selectors that *worked at +// the baseline but no longer do* — i.e. this branch likely broke them. +// +// Modes: +// node scripts/selector-diff-report.mjs report only +// node scripts/selector-diff-report.mjs --fix report + dry-run patch preview +// node scripts/selector-diff-report.mjs --apply report + write unambiguous fixes to disk +// node scripts/selector-diff-report.mjs --base compare against a different ref +// +// Never commits or pushes. --apply only ever restores a token this script +// has concrete baseline evidence for, and only when exactly one unambiguous +// candidate line is found in the current file — anything else is left for a +// human to resolve and is reported as "needs review". + +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { + repoRoot, + registryPath, + loadConfig, + extractSelectors, + applicationIndex, + validate, + identifyingTokens, + buildNeedles +} from "./selector-contract.mjs"; + +const args = process.argv.slice(2); +const mode = args.includes("--apply") ? "apply" : args.includes("--fix") ? "fix" : "report"; +const baseIndex = args.indexOf("--base"); +const baseRef = baseIndex !== -1 ? args[baseIndex + 1] : "origin/main"; + +const STATUS_RANK = { missing: 0, unverified: 1, exempt: 2, matched: 3 }; +const registryRelPath = path.relative(repoRoot, registryPath).replaceAll(path.sep, "/"); + +function git(argv) { + return execFileSync("git", argv, { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }); +} + +function readBaselineRegistry() { + try { + const raw = git(["show", `${baseRef}:${registryRelPath}`]); + return JSON.parse(raw); + } catch { + return null; + } +} + +function readBaselineFile(relPath) { + try { + return git(["show", `${baseRef}:${relPath}`]); + } catch { + return null; + } +} + +function findLineWithNeedle(text, needles) { + const lines = text.split("\n"); + for (let i = 0; i < lines.length; i += 1) { + if (needles.some((needle) => lines[i].includes(needle))) { + return { lineNumber: i + 1, text: lines[i] }; + } + } + return null; +} + +// Crude but dependency-free line-similarity score: fraction of shared +// "words" (tag names, attribute names/values) between two lines. Good +// enough to spot "this is clearly the same element, just missing the +// attribute" without pulling in a real HTML/Razor parser — consistent with +// how the rest of this tool already does plain-text scanning rather than +// AST-level analysis of the application source. +function similarity(lineA, lineB) { + const wordsOf = (line) => new Set(line.toLowerCase().match(/[a-z0-9_-]+/g) ?? []); + const a = wordsOf(lineA); + const b = wordsOf(lineB); + if (a.size === 0 || b.size === 0) return 0; + let shared = 0; + for (const word of a) if (b.has(word)) shared += 1; + return shared / Math.max(a.size, b.size); +} + +function findRestoreCandidate(oldLineText, oldLineNumber, currentFileText) { + const currentLines = currentFileText.split("\n"); + const scored = currentLines + .map((text, index) => { + const lineNumber = index + 1; + const score = similarity(oldLineText, text); + // An attribute rename/removal overwhelmingly happens in place — the + // element doesn't relocate elsewhere in the file. Use distance from + // the original line as a tiebreaker so two structurally-similar + // sibling lines (e.g. repeated `` + // rows) don't score as equally likely; it only ever nudges the + // ranking, never overrides a genuinely higher word-overlap score. + const proximityBonus = 1 / (1 + Math.abs(lineNumber - oldLineNumber)); + return { lineNumber, text, score, ranked: score + proximityBonus * 0.05 }; + }) + .filter((candidate) => candidate.score > 0) + .sort((a, b) => b.ranked - a.ranked); + + if (scored.length === 0 || scored[0].score < 0.6) return { candidate: null, reason: "no line above the similarity threshold" }; + if (scored.length > 1 && scored[1].ranked >= scored[0].ranked - 0.02) { + return { candidate: null, reason: `ambiguous — top two candidates score ${scored[0].score.toFixed(2)} (line ${scored[0].lineNumber}) and ${scored[1].score.toFixed(2)} (line ${scored[1].lineNumber})` }; + } + return { candidate: scored[0], reason: null }; +} + +function proposeInsertion(lineText, token) { + const attr = token.type === "id" ? "id" : token.type; + const tagMatch = lineText.match(/<([a-zA-Z][a-zA-Z0-9-]*)/); + if (!tagMatch) return null; + const insertAt = tagMatch.index + tagMatch[0].length; + return `${lineText.slice(0, insertAt)} ${attr}="${token.value}"${lineText.slice(insertAt)}`; +} + +function main() { + const config = loadConfig(); + const baseline = readBaselineRegistry(); + + if (!baseline) { + console.log(`No baseline registry found at ${baseRef}:${registryRelPath}.`); + console.log("This is expected before cypress/selectors/registry.json has been committed on the base branch."); + console.log("Run `npm run selectors:report` and commit the result on your base branch first, then re-run this."); + return; + } + + const currentEntries = validate(extractSelectors(config), config, applicationIndex(config)); + const baselineBySelector = new Map(baseline.entries.map((entry) => [entry.selector, entry])); + + const regressions = []; + const newlyBroken = []; + + for (const current of currentEntries) { + const before = baselineBySelector.get(current.selector); + if (!before) { + if (current.status === "missing") newlyBroken.push(current); + continue; + } + if (STATUS_RANK[current.status] < STATUS_RANK[before.status]) { + regressions.push({ before, current }); + } + } + + console.log(`Selector contract diff — base: ${baseRef}`); + console.log(` ${currentEntries.length} selectors on current tree, ${baseline.entries.length} at baseline`); + console.log(` regressions: ${regressions.length}, new-and-already-broken: ${newlyBroken.length}`); + console.log(""); + + if (regressions.length === 0 && newlyBroken.length === 0) { + console.log("No selector regressions found relative to the baseline."); + return; + } + + for (const { before, current } of regressions) { + console.log(`REGRESSED ${current.selector}`); + console.log(` status: ${before.status} -> ${current.status}`); + console.log(` used by: ${current.usedBy.join(", ")}`); + + if (before.status !== "matched" || current.status !== "missing") { + console.log(" (not auto-fixable — only matched -> missing regressions are attempted)\n"); + continue; + } + + const tokens = identifyingTokens(current.selector).filter((token) => + current.missingTokens.includes(`${token.type}:${token.value}`), + ); + + for (const token of tokens) { + const needles = buildNeedles(token); + let resolved = false; + + for (const relPath of before.applicationMatches) { + const oldFileText = readBaselineFile(relPath); + if (oldFileText === null) continue; + const oldLine = findLineWithNeedle(oldFileText, needles); + if (!oldLine) continue; + + const absPath = path.join(repoRoot, relPath); + if (!fs.existsSync(absPath)) { + console.log(` ${token.type}:${token.value} — baseline evidence in ${relPath}:${oldLine.lineNumber}, but that file no longer exists. NEEDS REVIEW.`); + resolved = true; + break; + } + + const currentFileText = fs.readFileSync(absPath, "utf8"); + const { candidate, reason } = findRestoreCandidate(oldLine.text, oldLine.lineNumber, currentFileText); + + if (!candidate) { + console.log(` ${token.type}:${token.value} — was in ${relPath}:${oldLine.lineNumber} (${oldLine.text.trim()}). NEEDS REVIEW: ${reason}.`); + resolved = true; + break; + } + + const fixedLine = proposeInsertion(candidate.text, token); + if (!fixedLine) { + console.log(` ${token.type}:${token.value} — matched ${relPath}:${candidate.lineNumber} but couldn't locate a tag to attach the attribute to. NEEDS REVIEW.`); + resolved = true; + break; + } + + console.log(` ${token.type}:${token.value} — proposed fix in ${relPath}:${candidate.lineNumber}`); + console.log(` - ${candidate.text.trim()}`); + console.log(` + ${fixedLine.trim()}`); + + if (mode === "apply") { + const lines = currentFileText.split("\n"); + lines[candidate.lineNumber - 1] = fixedLine; + fs.writeFileSync(absPath, lines.join("\n")); + console.log(` applied to ${relPath}`); + } + + resolved = true; + break; + } + + if (!resolved) { + console.log(` ${token.type}:${token.value} — no baseline evidence found to restore from. NEEDS REVIEW.`); + } + } + console.log(""); + } + + for (const entry of newlyBroken) { + console.log(`NEW, ALREADY MISSING ${entry.selector}`); + console.log(` used by: ${entry.usedBy.join(", ")}`); + console.log(` missing: ${entry.missingTokens.join(", ")}\n`); + } + + if (mode === "report") { + console.log("Run with --fix to preview proposed patches, or --apply to write unambiguous fixes to disk."); + } else if (mode === "fix") { + console.log("Dry run only — nothing was written. Re-run with --apply to write the unambiguous fixes above."); + } +} + +main(); diff --git a/applications/Unity.AutoUI/selector-contract.config.json b/applications/Unity.AutoUI/selector-contract.config.json new file mode 100644 index 000000000..71f7e4463 --- /dev/null +++ b/applications/Unity.AutoUI/selector-contract.config.json @@ -0,0 +1,27 @@ +{ + "cypressRoots": [ + "applications/Unity.AutoUI/cypress", + "applications/Unity.AutoUI/cypress_manyEmails" + ], + "applicationRoots": [ + "applications/Unity.GrantManager/src", + "applications/Unity.GrantManager/modules" + ], + "ownershipRules": [ + { + "pattern": "#(?:user|password|loginButton|social-(?:idir|azureidir))(?:$|[\\s>+~.,:[#])", + "ownership": "external", + "reason": "Identity-provider markup is not owned by Unity Grant Manager." + }, + { + "pattern": "#(?:bs-select-|select2-)|\\.dt-|\\.modal-backdrop|\\.swal2-|\\.select2-", + "ownership": "framework-generated", + "reason": "Selector is generated by a UI library at runtime." + }, + { + "pattern": "#formio|name=[\"']data\\[", + "ownership": "external", + "reason": "Form.io/CHEFS renders this markup dynamically." + } + ] +} diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsScriptBundleContributor.cs b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsScriptBundleContributor.cs index be08e7c39..6e0dead0b 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsScriptBundleContributor.cs +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsScriptBundleContributor.cs @@ -7,6 +7,7 @@ public class NotificationsScriptBundleContributor : BundleContributor { public override void ConfigureBundle(BundleConfigurationContext context) { - context.Files.AddIfNotContains("/js/notifications-realtime-client.js"); + context.Files.AddIfNotContains("/libs/select2/dist/js/select2.full.js"); + context.Files.AddIfNotContains("/libs/signalr/browser/signalr.min.js"); } } diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsStyleBundleContributor.cs b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsStyleBundleContributor.cs index 965f9a2d0..41f587b9e 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsStyleBundleContributor.cs +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Bundling/NotificationsStyleBundleContributor.cs @@ -7,6 +7,8 @@ public class NotificationsStyleBundleContributor : BundleContributor { public override void ConfigureBundle(BundleConfigurationContext context) { + context.Files.AddIfNotContains("/libs/select2/dist/css/select2.css"); + context.Files.AddIfNotContains("/libs/select2-bootstrap-5-theme/dist/select2-bootstrap-5-theme.css"); context.Files.AddIfNotContains("/libs/tinymce/skins/ui/oxide/content.css"); context.Files.AddIfNotContains("/libs/tinymce/skins/ui/oxide/skin.css"); } diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.cshtml b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.cshtml index d30863218..8f19d9215 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.cshtml +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.cshtml @@ -16,7 +16,7 @@ } -
+

@L["RealtimeOps:Title"]

diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.css b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.css index 986b7104c..12e8ae1cd 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.css +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Pages/UnityMessaging/Index.css @@ -1,3 +1,16 @@ +.messaging-page { + display: flex; + flex-direction: column; + height: calc(100vh - 70px); + height: calc(100dvh - 70px); + min-height: 0; +} + +.messaging-page > h3, +.messaging-page > .messaging-split-layout { + flex: 0 0 auto; +} + .messaging-split-layout { display: flex; align-items: stretch; @@ -37,10 +50,12 @@ } .messaging-activity-card { + flex: 1 1 auto; display: flex; flex-direction: column; - min-height: 320px; - height: calc(100vh - 390px); + min-height: 0; + height: auto; + margin-bottom: 0; overflow: hidden; } @@ -72,7 +87,8 @@ display: flex; flex: 1 1 auto; flex-direction: column; - overflow: hidden; + overflow: visible; + height: auto; } .messaging-activity-card #UnityMessagingActivityTable_wrapper .dt-layout-table, @@ -98,6 +114,10 @@ background: var(--bs-card-bg, #fff); } +.messaging-activity-card .dt-unity-footer { + margin-bottom: 1rem; +} + @media (max-width: 992px) { .messaging-split-layout { flex-direction: column; @@ -112,7 +132,13 @@ } .messaging-activity-card { + flex: 0 0 auto; height: auto; min-height: 420px; } + + .messaging-page { + height: auto; + min-height: 0; + } } \ No newline at end of file diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Realtime/NotificationHub.cs b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Realtime/NotificationHub.cs index 5e87ed9a8..625f5d081 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Realtime/NotificationHub.cs +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Realtime/NotificationHub.cs @@ -94,7 +94,9 @@ public async Task GetUnreadMessagesAsync() return [.. messages.Select(message => new UnreadMessageInfo { Scope = message.UserId.HasValue ? "user" : "tenant", - TargetId = message.UserId.HasValue ? userId.ToString() : message.TenantId?.ToString(), + TargetId = message.UserId.HasValue + ? message.SenderUserId?.ToString() + : message.TenantId?.ToString(), SenderId = message.SenderUserId?.ToString(), SenderName = message.SenderDisplayName ?? message.SenderUserId?.ToString() ?? "unknown", Source = message.Source, @@ -103,6 +105,54 @@ public async Task GetUnreadMessagesAsync() })]; } + public async Task GetConversationHistoryAsync(string scope, string? targetId) + { + if (!Guid.TryParse(GetCurrentUserId(), out var userId)) + { + return []; + } + + var query = await notificationLogsRepository.GetQueryableAsync(); + var messageQuery = query.Where(x => + x.NotificationType == NotificationLogType.SignalRDirectMessage + && x.TenantId == currentTenant.Id); + + if (scope == "tenant") + { + messageQuery = messageQuery.Where(x => x.UserId == null); + } + else if (Guid.TryParse(targetId, out var peerUserId)) + { + messageQuery = messageQuery.Where(x => + (x.UserId == userId && x.SenderUserId == peerUserId) + || (x.UserId == peerUserId && x.SenderUserId == userId)); + } + else + { + return []; + } + + var messages = await messageQuery + .OrderByDescending(x => x.CreationTime) + .Take(100) + .ToListAsync(); + + return [.. messages + .OrderBy(x => x.CreationTime) + .Select(message => new UnreadMessageInfo + { + Scope = message.UserId.HasValue ? "user" : "tenant", + TargetId = message.UserId.HasValue + ? (message.SenderUserId == userId ? message.UserId : message.SenderUserId)?.ToString() + : message.TenantId?.ToString(), + SenderId = message.SenderUserId?.ToString(), + SenderName = message.SenderDisplayName ?? message.SenderUserId?.ToString() ?? "unknown", + Source = message.Source, + Message = message.Message, + Timestamp = message.CreationTime + })]; + } + public Task MarkMessagesReadAsync() { return Guid.TryParse(GetCurrentUserId(), out var userId) diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/css/notifications-realtime-widget.css b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/css/notifications-realtime-widget.css index 0ba3c107f..d50a00aa3 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/css/notifications-realtime-widget.css +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/css/notifications-realtime-widget.css @@ -7,8 +7,8 @@ .rt-widget-bubble { position: relative; - width: 56px; - height: 56px; + width: 40px; + height: 40px; border-radius: 50%; border: none; background-color: #2e5dd7; @@ -19,6 +19,7 @@ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); cursor: pointer; padding: 0; + touch-action: none; } .rt-widget-bubble:hover { @@ -61,7 +62,7 @@ bottom: 0; width: 340px; max-width: 100vw; - max-height: 480px; + max-height: 80vh; background: #fff; border: 1px solid #dee2e6; border-bottom: none; @@ -70,7 +71,20 @@ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.08); display: none; flex-direction: column; - overflow: hidden; + overflow: visible; +} + +.rt-widget-resize-handle { + position: absolute; + right: 0; + bottom: 0; + z-index: 2; + width: 14px; + height: 16px; + cursor: nwse-resize; + touch-action: none; + clip-path: polygon(0% 100%, 100% 100%, 100% 0%); + background: repeating-linear-gradient(135deg, transparent 0 3px, rgba(108, 117, 125, .65) 4px 5px, transparent 3px 1px); } .rt-widget-panel-open { @@ -86,6 +100,12 @@ color: #fff; font-weight: 600; flex-shrink: 0; + cursor: grab; + touch-action: none; +} + +.rt-widget-panel-header:active { + cursor: grabbing; } .rt-widget-close { @@ -170,6 +190,8 @@ } .rt-widget-mode-tab { + display: flex; + align-items: center; flex: 1 1 50%; border: 1px solid #ced4da; background: #fff; @@ -180,6 +202,24 @@ cursor: pointer; } +.rt-widget-mode-count { + display: inline-block; + min-width: 16px; + margin-left: auto; + padding: 1px 4px; + border-radius: 8px; + background-color: #6c757d; + color: #fff; + font-size: 0.7rem; + line-height: 1.2; + text-align: center; + vertical-align: 1px; +} + +.rt-widget-mode-count.rt-widget-hidden { + display: none; +} + .rt-widget-mode-tab.active { border-color: #2e5dd7; background: #2e5dd7; @@ -208,9 +248,52 @@ width: 100%; min-width: 0; font-size: 0.85rem; - padding: 4px 6px 4px 25px; - border: 1px solid #ced4da; - border-radius: 4px; + padding-left: 25px; +} + +.rt-widget-target-control .select2-container { + width: 100% !important; +} + +.rt-widget-target-control .select2-container--bootstrap-5.select2-container--focus { + outline: 0 !important; +} + +.rt-widget-target-control .select2-container--bootstrap-5.select2-container--focus .select2-selection { + border-color: #dee2e6 !important; + box-shadow: none !important; +} + +.rt-widget-target-control .select2-container--open, +.rt-widget-target-control .select2-dropdown { + z-index: 1057; +} + +.rt-widget-target-control .select2-container--open .select2-selection { + box-shadow: none !important; +} + +.rt-widget-target-control .select2-selection--single { + height: 31px; + padding-left: 18px; +} + +.rt-widget-target-control .select2-selection__rendered { + font-size: 0.85rem; + line-height: 29px; +} + +.rt-widget-target-control .select2-results__option { + min-height: 32px; + font-size: 0.85rem; +} + +.rt-widget-target-option-content { + display: flex; + align-items: center; + gap: 4px; + min-height: 20px; + white-space: nowrap; } .rt-widget-compose-row { diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/js/notifications-realtime-client.js b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/js/notifications-realtime-client.js index 787361173..c8e2e63d1 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/js/notifications-realtime-client.js +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/wwwroot/js/notifications-realtime-client.js @@ -15,25 +15,49 @@ } } - function init() { - if (/\/(account\/login|login|splash)(?:\/|$)/i.test(window.location.pathname)) { - return; - } + function shouldInit() { + shouldInit.depth = (shouldInit.depth || 0) + 1; + + try { + if (shouldInit.depth > 10) { + console.error('RECURSIVE shouldInit DETECTED'); + console.trace(); + return false; + } - if (window.location.pathname === '/') { - return; - } + const path = window.location.pathname.toLowerCase(); + const guardedPaths = ['/account/login', '/login', '/splash']; - if (abp.features && typeof abp.features.isEnabled === 'function' - && !abp.features.isEnabled('Unity.Notifications.DirectMessaging')) { - return; - } + for (const guardedPath of guardedPaths) { + if (path.includes(guardedPath)) { + return false; + } + } - if (typeof signalR === 'undefined') { - return; + if (path === '/') { + return false; + } + + if (!window.abp) { + return false; + } + + if (!window.abp?.currentUser?.isAuthenticated) { + return false; + } + + if (!window.signalR) { + return false; + } + + return true; + } finally { + shouldInit.depth--; } + } - if (!window.abp?.currentUser?.isAuthenticated) { + function init() { + if (!shouldInit()) { return; } @@ -47,16 +71,42 @@ let peers = []; let activeMode = 'individual'; let currentTenant = null; + const selectedTargets = { individual: '', tenant: '' }; + const modeNotificationCounts = { individual: 0, tenant: 0 }; + let targetSelect2Open = false; + let targetOptionsRefreshPending = false; const histories = {}; const MAX_HISTORY_ITEMS = 100; const STATUS_GREEN_MS = 10 * 60 * 1000; const STATUS_ORANGE_MS = 30 * 60 * 1000; + const BUBBLE_POSITION_STORAGE_KEY = 'unity.notifications.realtime.bubble-position'; + const PANEL_SIZE_STORAGE_KEY = 'unity.notifications.realtime.panel-size'; + const PANEL_POSITION_STORAGE_KEY = 'unity.notifications.realtime.panel-position'; const widget = buildWidget(); + setupBubbleDragging(); + setupPanelResizing(); + setupPanelDragging(); + setupTargetSelect2(); const connection = new signalR.HubConnectionBuilder() .withUrl('/signalr/notifications') .withAutomaticReconnect() .build(); + let connectionStartTask = null; + + function startConnection() { + if (connection.state === signalR.HubConnectionState.Connected) { + return Promise.resolve(); + } + + if (!connectionStartTask) { + connectionStartTask = connection.start().finally(function () { + connectionStartTask = null; + }); + } + + return connectionStartTask; + } connection.on('directMessageReceived', function (eventData) { const scope = eventData?.scope || 'user'; @@ -75,16 +125,13 @@ addMessage(mode, targetId, sender, senderId, message, eventData?.timestamp); if (scope === 'user') { - activeMode = 'individual'; ensurePeerOption(senderId, sender); - } else { - activeMode = 'tenant'; } - widget.modeTabs.forEach(tab => tab.classList.toggle('active', tab.dataset.mode === activeMode)); - renderTargetOptions(); - widget.target.value = targetId; - renderConversation(); + if (senderId !== myUserId) { + modeNotificationCounts[mode] += 1; + updateModeTabCounts(); + } if (eventData.source === 'UnityMessagingController' && senderId && senderId !== myUserId) { showIncomingToast(sender, message); @@ -98,10 +145,10 @@ const HEARTBEAT_INTERVAL_MS = 5 * 60 * 1000; const ACTIVITY_HEARTBEAT_THROTTLE_MS = 60 * 1000; - const ACTIVITY_EVENTS = ['click', 'keydown', 'mousemove', 'scroll']; + const ACTIVITY_EVENTS = ['click', 'keydown', 'scroll']; let lastHeartbeatSentAt = 0; - connection.start().then(function () { + startConnection().then(function () { sendHeartbeat(true); refreshPeers(); refreshTenant(); @@ -121,15 +168,27 @@ } connection.invoke('GetUnreadMessagesAsync').then(function (messages) { + let firstUnreadMode = null; + let firstUnreadTarget = null; + (Array.isArray(messages) ? messages : []).forEach(function (eventData) { const scope = eventData.scope === 'tenant' ? 'tenant' : 'user'; const senderId = eventData.senderId || null; - const targetId = scope === 'tenant' ? eventData.targetId : senderId; + const targetId = scope === 'tenant' + ? eventData.targetId + : eventData.targetId || senderId; if (!targetId) { return; } + modeNotificationCounts[scope === 'tenant' ? 'tenant' : 'individual'] += 1; + + if (!firstUnreadTarget) { + firstUnreadMode = scope === 'tenant' ? 'tenant' : 'individual'; + firstUnreadTarget = targetId; + } + addMessage( scope === 'tenant' ? 'tenant' : 'individual', targetId, @@ -147,6 +206,19 @@ showIncomingToast(eventData.senderName || senderId, eventData.message || ''); } }); + + if (firstUnreadTarget) { + activeMode = firstUnreadMode; + widget.modeTabs.forEach(function (tab) { + tab.classList.toggle('active', tab.dataset.mode === activeMode); + }); + renderTargetOptions(); + widget.target.value = firstUnreadTarget; + refreshTargetSelect2(); + renderConversation(); + } + + updateModeTabCounts(); }).catch(function () { // Unread history is a convenience; realtime delivery remains available. }); @@ -184,6 +256,12 @@ peers = (Array.isArray(result) ? result : []).filter(function (p) { return p?.userId && p.userId !== myUserId; }); + + if (targetSelect2Open) { + targetOptionsRefreshPending = true; + return; + } + renderTargetOptions(); } @@ -194,6 +272,12 @@ connection.invoke('GetCurrentTenantAsync').then(function (result) { currentTenant = result || null; + + if (targetSelect2Open) { + targetOptionsRefreshPending = true; + return; + } + renderTargetOptions(); }).catch(function () { currentTenant = null; @@ -201,7 +285,12 @@ } function renderTargetOptions() { - const currentValue = widget.target.value; + if (targetSelect2Open || (window.jQuery?.('.select2-container--open').length > 0)) { + targetOptionsRefreshPending = true; + return; + } + + const currentValue = selectedTargets[activeMode] || widget.target.value; if (activeMode === 'tenant') { widget.targetControl.style.display = 'none'; @@ -211,7 +300,9 @@ widget.target.disabled = !currentTenant; if (currentTenant) { widget.target.value = currentTenant.id; + selectedTargets.tenant = currentTenant.id; } + refreshTargetSelect2(); updateTargetStatusDot(); renderConversation(); return; @@ -222,6 +313,7 @@ if (peers.length === 0) { widget.target.innerHTML = ``; widget.target.disabled = true; + refreshTargetSelect2(); updateTargetStatusDot(); return; } @@ -229,19 +321,117 @@ widget.target.disabled = false; widget.target.innerHTML = `` + peers .map(function (p) { - const suffix = p.isOnline ? '' : ` (${l('RealtimeWidget:StatusOffline')})`; - return ``; + return ``; }) .join(''); if (currentValue && peers.some(function (p) { return p.userId === currentValue; })) { widget.target.value = currentValue; + selectedTargets.individual = currentValue; } + refreshTargetSelect2(); updateTargetStatusDot(); renderConversation(); } + function setupTargetSelect2() { + if (!window.jQuery || !window.jQuery.fn?.select2) { + return; + } + + window.jQuery(widget.target).select2({ + theme: 'bootstrap-5', + width: '100%', + placeholder: l('RealtimeWidget:To'), + allowClear: true, + dropdownParent: window.jQuery(widget.targetControl), + templateResult: renderTargetSelect2Option, + templateSelection: renderTargetSelect2Option, + escapeMarkup: function (markup) { return markup; } + }); + + window.jQuery(widget.target) + .on('select2:open', function () { + targetSelect2Open = true; + syncTargetSelect2DropdownSize(); + }) + .on('select2:close', function () { + targetSelect2Open = false; + if (targetOptionsRefreshPending) { + targetOptionsRefreshPending = false; + renderTargetOptions(); + } else { + refreshTargetSelect2(); + } + }); + + window.addEventListener('resize', syncTargetSelect2DropdownSize); + } + + function syncTargetSelect2DropdownSize() { + if (!window.jQuery?.fn?.select2 || !window.jQuery(widget.target).data('select2')) { + return; + } + + const dropdown = widget.targetControl.querySelector('.select2-dropdown'); + if (dropdown && window.jQuery?.('.select2-container--open').length > 0) { + dropdown.style.setProperty('width', `${widget.targetControl.getBoundingClientRect().width}px`, 'important'); + } + } + + function refreshTargetSelect2() { + const select2MenuOpen = targetSelect2Open + || (window.jQuery?.('.select2-container--open').length > 0); + + if (!select2MenuOpen + && window.jQuery + && window.jQuery.fn?.select2 + && window.jQuery(widget.target).data('select2')) { + window.jQuery(widget.target).trigger('change.select2'); + } + } + + function renderTargetSelect2Option(data) { + if (!data.id) { + return data.text; + } + + const peer = peers.find(function (item) { return item.userId === data.id; }); + const status = activeMode === 'tenant' ? null : getPeerStatus(peer); + const statusMarkup = status + ? `` + : ''; + + return `${statusMarkup}${escapeHtml(data.text)}`; + } + + function loadConversationHistory(mode, targetId) { + if (!targetId || connection.state !== signalR.HubConnectionState.Connected) { + return; + } + + connection.invoke('GetConversationHistoryAsync', mode, targetId).then(function (messages) { + if (activeMode !== mode || widget.target.value !== targetId) { + return; + } + + const key = `${mode}:${targetId}`; + histories[key] = (Array.isArray(messages) ? messages : []).map(function (eventData) { + return { + sender: eventData.senderName || eventData.senderId || 'unknown', + senderId: eventData.senderId || null, + message: eventData.message || '', + timestamp: eventData.timestamp, + mode + }; + }).slice(-MAX_HISTORY_ITEMS); + renderConversation(); + }).catch(function () { + // Conversation history is optional; realtime and unread messages remain available. + }); + } + function getPeerStatus(peer) { if (!peer?.isOnline) { return { className: 'offline', label: l('RealtimeWidget:StatusOffline') }; @@ -270,21 +460,343 @@ } const peer = peers.find(function (p) { return p.userId === widget.target.value; }); + if (!peer || !widget.target.value) { + widget.targetStatus.className = 'rt-status-dot rt-widget-target-status rt-status-hidden'; + widget.targetStatus.removeAttribute('title'); + return; + } + const status = getPeerStatus(peer); widget.targetStatus.className = `rt-status-dot rt-widget-target-status rt-status-${status.className}`; widget.targetStatus.title = status.label; } + function setupBubbleDragging() { + let dragState = null; + let suppressNextClick = false; + + restoreBubblePosition(); + + widget.bubble.addEventListener('pointerdown', function (event) { + if (event.button !== 0) { + return; + } + + const bounds = widget.container.getBoundingClientRect(); + dragState = { + startX: event.clientX, + startY: event.clientY, + left: bounds.left, + top: bounds.top, + moved: false + }; + widget.bubble.setPointerCapture(event.pointerId); + event.preventDefault(); + }); + + widget.bubble.addEventListener('pointermove', function (event) { + if (!dragState) { + return; + } + + const deltaX = event.clientX - dragState.startX; + const deltaY = event.clientY - dragState.startY; + dragState.moved = dragState.moved || Math.abs(deltaX) > 3 || Math.abs(deltaY) > 3; + + if (!dragState.moved) { + return; + } + + const position = clampBubblePosition( + dragState.left + deltaX, + dragState.top + deltaY + ); + setBubblePosition(position.left, position.top); + event.preventDefault(); + }); + + widget.bubble.addEventListener('pointerup', finishDrag); + widget.bubble.addEventListener('pointercancel', finishDrag); + + widget.bubble.addEventListener('click', function (event) { + if (suppressNextClick) { + suppressNextClick = false; + event.preventDefault(); + event.stopImmediatePropagation(); + } + }, true); + + function finishDrag(event) { + if (!dragState) { + return; + } + + if (dragState.moved) { + const bounds = widget.container.getBoundingClientRect(); + saveBubblePosition(bounds.left, bounds.top); + suppressNextClick = true; + } + + if (widget.bubble.hasPointerCapture(event.pointerId)) { + widget.bubble.releasePointerCapture(event.pointerId); + } + dragState = null; + } + } + + function clampBubblePosition(left, top) { + const bounds = widget.bubble.getBoundingClientRect(); + const margin = 8; + const maxLeft = Math.max(margin, window.innerWidth - bounds.width - margin); + const maxTop = Math.max(margin, window.innerHeight - bounds.height - margin); + + return { + left: Math.min(Math.max(left, margin), maxLeft), + top: Math.min(Math.max(top, margin), maxTop) + }; + } + + function setBubblePosition(left, top) { + widget.container.style.left = `${left}px`; + widget.container.style.top = `${top}px`; + widget.container.style.right = 'auto'; + widget.container.style.bottom = 'auto'; + } + + function reportNonFatalError(message, error) { + console.warn(message, error); + } + + function saveBubblePosition(left, top) { + try { + localStorage.setItem(BUBBLE_POSITION_STORAGE_KEY, JSON.stringify({ left, top })); + } catch (error) { + reportNonFatalError('Unable to save bubble position.', error); + } + } + + function restoreBubblePosition() { + try { + const storedPosition = JSON.parse(localStorage.getItem(BUBBLE_POSITION_STORAGE_KEY)); + if (Number.isFinite(storedPosition?.left) && Number.isFinite(storedPosition?.top)) { + const position = clampBubblePosition(storedPosition.left, storedPosition.top); + setBubblePosition(position.left, position.top); + } + } catch (error) { + reportNonFatalError('Unable to restore bubble position.', error); + } + } + + function setupPanelResizing() { + let resizeState = null; + + restorePanelSize(); + + widget.resizeHandle.addEventListener('pointerdown', function (event) { + if (event.button !== 0) { + return; + } + + const bounds = widget.panel.getBoundingClientRect(); + resizeState = { + startX: event.clientX, + startY: event.clientY, + width: bounds.width, + height: bounds.height + }; + widget.resizeHandle.setPointerCapture(event.pointerId); + event.preventDefault(); + event.stopPropagation(); + }); + + widget.resizeHandle.addEventListener('pointermove', function (event) { + if (!resizeState) { + return; + } + + const size = clampPanelSize( + resizeState.width + event.clientX - resizeState.startX, + resizeState.height + event.clientY - resizeState.startY + ); + widget.panel.style.width = `${size.width}px`; + widget.panel.style.height = `${size.height}px`; + syncTargetSelect2DropdownSize(); + event.preventDefault(); + }); + + widget.resizeHandle.addEventListener('pointerup', finishResize); + widget.resizeHandle.addEventListener('pointercancel', finishResize); + + function finishResize(event) { + if (!resizeState) { + return; + } + + const bounds = widget.panel.getBoundingClientRect(); + savePanelSize(bounds.width, bounds.height); + + if (widget.resizeHandle.hasPointerCapture(event.pointerId)) { + widget.resizeHandle.releasePointerCapture(event.pointerId); + } + resizeState = null; + } + } + + function setupPanelDragging() { + let dragState = null; + + restorePanelPosition(); + + widget.header.addEventListener('pointerdown', function (event) { + if (event.button !== 0 || event.target.closest('button')) { + return; + } + + const bounds = widget.panel.getBoundingClientRect(); + setPanelPosition(bounds.left, bounds.top); + dragState = { + startX: event.clientX, + startY: event.clientY, + left: bounds.left, + top: bounds.top + }; + widget.header.setPointerCapture(event.pointerId); + event.preventDefault(); + }); + + widget.header.addEventListener('pointermove', function (event) { + if (!dragState) { + return; + } + + const position = clampPanelPosition( + dragState.left + event.clientX - dragState.startX, + dragState.top + event.clientY - dragState.startY + ); + setPanelPosition(position.left, position.top); + event.preventDefault(); + }); + + widget.header.addEventListener('pointerup', finishDrag); + widget.header.addEventListener('pointercancel', finishDrag); + + function finishDrag(event) { + if (!dragState) { + return; + } + + const bounds = widget.panel.getBoundingClientRect(); + savePanelPosition(bounds.left, bounds.top); + + if (widget.header.hasPointerCapture(event.pointerId)) { + widget.header.releasePointerCapture(event.pointerId); + } + dragState = null; + } + } + + function clampPanelPosition(left, top) { + const bounds = widget.panel.getBoundingClientRect(); + const margin = 8; + const maxLeft = Math.max(margin, window.innerWidth - bounds.width - margin); + const maxTop = Math.max(margin, window.innerHeight - bounds.height - margin); + + return { + left: Math.min(Math.max(left, margin), maxLeft), + top: Math.min(Math.max(top, margin), maxTop) + }; + } + + function setPanelPosition(left, top) { + widget.panel.style.left = `${left}px`; + widget.panel.style.top = `${top}px`; + widget.panel.style.right = 'auto'; + widget.panel.style.bottom = 'auto'; + } + + function savePanelPosition(left, top) { + try { + localStorage.setItem(PANEL_POSITION_STORAGE_KEY, JSON.stringify({ left, top })); + } catch (error) { + reportNonFatalError('Unable to save panel position.', error); + } + } + + function restorePanelPosition() { + try { + const storedPosition = JSON.parse(localStorage.getItem(PANEL_POSITION_STORAGE_KEY)); + if (Number.isFinite(storedPosition?.left) && Number.isFinite(storedPosition?.top)) { + setPanelPosition(storedPosition.left, storedPosition.top); + } + } catch (error) { + reportNonFatalError('Unable to restore panel position.', error); + } + } + + function clampPanelSize(width, height) { + const margin = 16; + const minWidth = 260; + const minHeight = 240; + const maxWidth = Math.max(minWidth, window.innerWidth - margin * 2); + const maxHeight = Math.max(minHeight, window.innerHeight - margin * 2); + + return { + width: Math.min(Math.max(width, minWidth), maxWidth), + height: Math.min(Math.max(height, minHeight), maxHeight) + }; + } + + function savePanelSize(width, height) { + try { + localStorage.setItem(PANEL_SIZE_STORAGE_KEY, JSON.stringify({ width, height })); + } catch (error) { + reportNonFatalError('Unable to save panel size.', error); + } + } + + function restorePanelSize() { + try { + const storedSize = JSON.parse(localStorage.getItem(PANEL_SIZE_STORAGE_KEY)); + if (Number.isFinite(storedSize?.width) && Number.isFinite(storedSize?.height)) { + const size = clampPanelSize(storedSize.width, storedSize.height); + widget.panel.style.width = `${size.width}px`; + widget.panel.style.height = `${size.height}px`; + } + } catch (error) { + reportNonFatalError('Unable to restore panel size.', error); + } + } + widget.composeSend.addEventListener('click', sendComposeMessage); widget.target.addEventListener('change', function () { + selectedTargets[activeMode] = widget.target.value; updateTargetStatusDot(); renderConversation(); }); + if (window.jQuery) { + window.jQuery(widget.target).on('select2:select select2:clear', function () { + selectedTargets[activeMode] = widget.target.value; + updateTargetStatusDot(); + renderConversation(); + + if (widget.target.value) { + loadConversationHistory(activeMode, widget.target.value); + } + }); + } widget.modeTabs.forEach(function (tab) { tab.addEventListener('click', function () { + selectedTargets[activeMode] = widget.target.value; activeMode = tab.dataset.mode; + modeNotificationCounts[activeMode] = 0; + updateModeTabCounts(); widget.modeTabs.forEach(item => item.classList.toggle('active', item === tab)); renderTargetOptions(); + renderConversation(); + + if (widget.target.value) { + loadConversationHistory(activeMode, widget.target.value); + } }); }); widget.composeInput.addEventListener('keydown', function (e) { @@ -295,6 +807,7 @@ }); function sendComposeMessage() { + const messageMode = activeMode; const targetId = widget.target.value; const message = widget.composeInput.value.trim(); @@ -306,18 +819,29 @@ return; } - if (connection.state !== signalR.HubConnectionState.Connected) { - return; - } + const sendTask = startConnection().then(function () { + if (connection.state !== signalR.HubConnectionState.Connected) { + throw new Error('Realtime connection is unavailable.'); + } - const sendTask = activeMode === 'tenant' - ? connection.invoke('SendTenantMessageAsync', message) - : connection.invoke('SendPeerMessageAsync', targetId, message); + return activeMode === 'tenant' + ? connection.invoke('SendTenantMessageAsync', message) + : connection.invoke('SendPeerMessageAsync', targetId, message); + }); sendTask.then(function () { - if (activeMode !== 'tenant') { - addMessage(activeMode, targetId, l('RealtimeWidget:You'), null, message, new Date().toISOString()); + if (messageMode !== 'tenant') { + addMessage(messageMode, targetId, l('RealtimeWidget:You'), null, message, new Date().toISOString()); } + + activeMode = messageMode; + widget.modeTabs.forEach(function (tab) { + tab.classList.toggle('active', tab.dataset.mode === activeMode); + }); + renderTargetOptions(); + widget.target.value = targetId; + refreshTargetSelect2(); + renderConversation(); widget.composeInput.value = ''; }).catch(function () { // Recipient is invalid or outside the tenant; leave the draft in place. @@ -431,6 +955,20 @@ } } + function updateModeTabCounts() { + widget.modeTabs.forEach(function (tab) { + const count = modeNotificationCounts[tab.dataset.mode] || 0; + const countElement = tab.querySelector('.rt-widget-mode-count'); + + if (!countElement) { + return; + } + + countElement.textContent = count > 9 ? '9+' : String(count); + countElement.classList.toggle('rt-widget-hidden', count === 0); + }); + } + function togglePanel() { panelOpen = !panelOpen; widget.panel.classList.toggle('rt-widget-panel-open', panelOpen); @@ -464,6 +1002,12 @@ const panel = document.createElement('div'); panel.className = 'rt-widget-panel'; + const resizeHandle = document.createElement('span'); + resizeHandle.className = 'rt-widget-resize-handle'; + resizeHandle.setAttribute('role', 'presentation'); + resizeHandle.setAttribute('aria-hidden', 'true'); + panel.appendChild(resizeHandle); + const header = document.createElement('div'); header.className = 'rt-widget-panel-header'; @@ -499,12 +1043,14 @@ individualTab.className = 'rt-widget-mode-tab active'; individualTab.dataset.mode = 'individual'; individualTab.textContent = l('RealtimeWidget:Individual'); + appendModeCount(individualTab); const tenantTab = document.createElement('button'); tenantTab.type = 'button'; tenantTab.className = 'rt-widget-mode-tab'; tenantTab.dataset.mode = 'tenant'; tenantTab.textContent = l('RealtimeWidget:Tenant'); + appendModeCount(tenantTab); modeTabs.appendChild(individualTab); modeTabs.appendChild(tenantTab); @@ -566,7 +1112,13 @@ container.appendChild(bubble); document.body.appendChild(container); - return { container, panel, list, bubble, badge, modeTabs: [individualTab, tenantTab], targetControl, target, targetStatus, composeInput, composeSend }; + return { container, panel, list, bubble, badge, resizeHandle, header, modeTabs: [individualTab, tenantTab], targetControl, target, targetStatus, composeInput, composeSend }; + + function appendModeCount(tab) { + const count = document.createElement('span'); + count.className = 'rt-widget-mode-count rt-widget-hidden'; + tab.appendChild(count); + } } } })(); diff --git a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Bundling/UnityThemeUX2GlobalScriptContributor.cs b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Bundling/UnityThemeUX2GlobalScriptContributor.cs index 2ae3ac12f..836c089f1 100644 --- a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Bundling/UnityThemeUX2GlobalScriptContributor.cs +++ b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Bundling/UnityThemeUX2GlobalScriptContributor.cs @@ -31,6 +31,7 @@ public override void ConfigureBundle(BundleConfigurationContext context) context.Files.AddIfNotContains("/libs/datatables.net-colreorder-bs5/js/colReorder.bootstrap5.min.js"); context.Files.AddIfNotContains("/libs/echarts/echarts.min.js"); + context.Files.AddIfNotContains("/libs/tributejs/dist/tribute.min.js"); context.Files.AddIfNotContains("/libs/tinymce/tinymce.min.js"); context.Files.AddIfNotContains("/libs/tinymce/themes/silver/theme.min.js"); diff --git a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Account.cshtml b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Account.cshtml index 2057a67b9..aa1901920 100644 --- a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Account.cshtml +++ b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Account.cshtml @@ -99,11 +99,6 @@
- @* Loaded outside the bundle: re-minifying these already-minified libraries alongside the rest - of UX2.Global risks corrupting their internal closures (observed for SignalR's - automatic-reconnect logic; tribute.js's active regex scanning is suspected similarly). *@ - - diff --git a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Application.cshtml b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Application.cshtml index 6a5fb4490..a797d7d9f 100644 --- a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Application.cshtml +++ b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Application.cshtml @@ -109,12 +109,8 @@ @await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Application)
- @* Loaded outside the bundle: re-minifying these already-minified libraries alongside the rest - of UX2.Global risks corrupting their internal closures (observed for SignalR's - automatic-reconnect logic; tribute.js's active regex scanning is suspected similarly). *@ - - + diff --git a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Empty.cshtml b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Empty.cshtml index c11e64cb7..9bf7c310f 100644 --- a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Empty.cshtml +++ b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/Themes/UX2/Layouts/Empty.cshtml @@ -65,12 +65,6 @@
- - @* Loaded outside the bundle: re-minifying these already-minified libraries alongside the rest - of UX2.Global risks corrupting their internal closures (observed for SignalR's - automatic-reconnect logic; tribute.js's active regex scanning is suspected similarly). *@ - - diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/GrantManagerWebModule.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/GrantManagerWebModule.cs index 967b5087c..ed4a513a2 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/GrantManagerWebModule.cs +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/GrantManagerWebModule.cs @@ -481,6 +481,8 @@ private void ConfigureBundles() { Configure(options => { + options.Mode = BundlingMode.BundleAndMinify; + options.MinificationIgnoredFiles.Add("/js/notifications-realtime-client.js"); options .StyleBundles .Configure(UnityThemeUX2Bundles.Styles.Global, bundle => diff --git a/applications/Unity.Tools/Unity.NginxData/nginx.conf b/applications/Unity.Tools/Unity.NginxData/nginx.conf index e395b4a9e..1acafb0f3 100644 --- a/applications/Unity.Tools/Unity.NginxData/nginx.conf +++ b/applications/Unity.Tools/Unity.NginxData/nginx.conf @@ -1,5 +1,5 @@ worker_processes auto; -error_log /var/log/nginx/error.log; +error_log /dev/stderr; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. @@ -12,9 +12,9 @@ events { http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; + '"$http_user_agent" "$http_x_forwarded_for" "$host"'; - access_log /var/log/nginx/access.log main; + access_log /dev/stdout main; sendfile on; tcp_nopush on; @@ -33,7 +33,7 @@ http { # Enable gzip compression gzip on; - gzip_types text/plain application/json application/javascript text/css text/xml application/xml application/xml+rss text/javascript; + gzip_types text/plain application/json application/geo+json application/javascript text/css text/xml application/xml application/xml+rss text/javascript; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include @@ -71,7 +71,14 @@ http { add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; } - + + # Confirmed safe: CHEFS consumes /reference/ via client-session browser + # fetch/XHR/img, not window.open(), so COOP has no effect on this path. + add_header X-Content-Type-Options "nosniff" always; + add_header Cross-Origin-Opener-Policy "same-origin" always; + add_header Cross-Origin-Resource-Policy "cross-origin" always; + add_header Cache-Control "public, max-age=86400" always; + try_files $uri $uri/ =404; } @@ -83,11 +90,7 @@ http { } # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header Referrer-Policy "no-referrer-when-downgrade" always; - add_header Content-Security-Policy "default-src 'self'; style-src 'self'; font-src 'self'; script-src 'self'; object-src 'none';" always; # Cross-origin isolation headers (scan findings) # COOP: restricts cross-origin window access add_header Cross-Origin-Opener-Policy "same-origin" always; @@ -105,9 +108,5 @@ http { error_page 500 502 503 504 /50x.html; location = /50x.html { } - - location /grants { - return 404; - } } }