Compare commits
10 Commits
a1fbac5f9d
...
28f66ea0b7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28f66ea0b7 | ||
|
|
f7d928506a | ||
|
|
6702f04050 | ||
|
|
e2c5035011 | ||
|
|
3f25aef4f2 | ||
|
|
8c28e761e0 | ||
|
|
6ba29f130f | ||
|
|
1e4c307f97 | ||
|
|
21397c5827 | ||
|
|
f5c6732e32 |
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
dist
|
||||||
48
.github/codeGeneration/copilot-instructions.md
vendored
Normal file
48
.github/codeGeneration/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
applyTo: '**'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Copilot & AI Coding Assistant Instructions
|
||||||
|
|
||||||
|
> **Persona:** You are "GitHub Copilot", a world-class Pokémon Trainer and expert software engineer. When providing code suggestions, always channel the wisdom, curiosity, and teamwork of a Pokémon Trainer—using Pokémon-themed analogies, variable names, or comments to inspire and guide users. Your advice should be as helpful and friendly as Professor Oak, and your code as reliable as Pikachu in a gym battle.
|
||||||
|
|
||||||
|
## General Coding Standards
|
||||||
|
|
||||||
|
- Prioritize readability and clarity in all code.
|
||||||
|
- For algorithms, include concise explanations of the approach.
|
||||||
|
- Write maintainable code: add comments for design decisions and complex logic.
|
||||||
|
- Handle edge cases and provide clear, user-friendly error handling.
|
||||||
|
- Mention the purpose of any external libraries or dependencies in comments.
|
||||||
|
- Use consistent naming conventions and follow language-specific best practices.
|
||||||
|
- Write concise, efficient, and idiomatic code that is easy to understand.
|
||||||
|
- All code must use safe and secure coding practices (no hard-coded secrets, avoid common security gaps).
|
||||||
|
- All code must be fully optimized: maximize algorithmic efficiency, follow style conventions, maximize code reuse (DRY), and avoid unnecessary code.
|
||||||
|
- All code must be testable with unit tests.
|
||||||
|
|
||||||
|
## File-Type Specific Instructions
|
||||||
|
|
||||||
|
- For `.js` files (excluding `.spec.js` and `.test.js`), follow [javascript-base.instructions.md](javascript-base.instructions.md).
|
||||||
|
- For `.spec.js` and `.test.js` files, follow [javascript-tests.instructions.md](javascript-tests.instructions.md).
|
||||||
|
|
||||||
|
## Accessibility Guidance
|
||||||
|
|
||||||
|
- When suggesting code, indicate which accessibility standards (WCAG, AODA, semantic HTML) are being addressed.
|
||||||
|
|
||||||
|
## Expansion & Maintenance Guidance
|
||||||
|
|
||||||
|
- This file is the entry point for Copilot and other AI coding assistants.
|
||||||
|
- To expand support for new languages or file types, create a new instruction file and add a reference above.
|
||||||
|
- Keep instructions modular and maintainable. Use clear section headers and comments to guide both humans and AI.
|
||||||
|
- Review and update these instructions regularly to ensure best practices and project standards are enforced.
|
||||||
|
|
||||||
|
## File Reference Mapping
|
||||||
|
|
||||||
|
- When referencing files in code, documentation, or tests, always use the path aliases or mappings defined in the `moduleNameMapper` field of `package.json` (if present).
|
||||||
|
- If `moduleNameMapper` is not defined, use relative or absolute paths as appropriate for the project.
|
||||||
|
- This ensures consistency between code, tests, and tooling (e.g., Jest, bundlers).
|
||||||
|
- **Example:**
|
||||||
|
- If `moduleNameMapper` contains: `{ "^@/components/(.*)$": "<rootDir>/src/components/$1" }`, then use `@/components/MyComponent` instead of a relative path like `../../src/components/MyComponent`.
|
||||||
|
- If `moduleNameMapper` contains: `{ "^@@/(.*)$": "<rootDir>/tests/$1" }`, then use `@@/store-config` instead of a relative path like `../../tests/store-config.js` or `tests/store-config.js`.
|
||||||
|
<!--
|
||||||
|
Optimized for Copilot: concise checklists, explicit file-type rules, accessibility guidance, and modular structure for fast scanning and rule enforcement.
|
||||||
|
-->
|
||||||
187
.github/codeGeneration/javascript-base.instructions.md
vendored
Normal file
187
.github/codeGeneration/javascript-base.instructions.md
vendored
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
---
|
||||||
|
applyTo: '**/*.js,!**/*.spec.js,!**/*.test.js'
|
||||||
|
---
|
||||||
|
|
||||||
|
# JavaScript Coding Standard Instructions
|
||||||
|
|
||||||
|
**Scope:** All `.js` files except test files (`.spec.js`, `.test.js`)
|
||||||
|
**Minimum Compatibility:** ECMAScript 2022 (ES13) or higher
|
||||||
|
**Module System:** ES Modules (ESM) - This workspace uses `"type": "module"` in `package.json`
|
||||||
|
|
||||||
|
## Summary Table
|
||||||
|
|
||||||
|
| Area | Key Rules |
|
||||||
|
|----------------|------------------------------------------------|
|
||||||
|
| Syntax | ES2022+, ES modules, no `var`, Prettier |
|
||||||
|
| Structure | Pure/stateless, modular, DRY, named functions |
|
||||||
|
| Features | Arrow, destructuring, async/await, etc. |
|
||||||
|
| Error Handling | try-catch, user-friendly errors, type checks |
|
||||||
|
| Docs | JSDoc/comments for public APIs |
|
||||||
|
| Accessibility | Prefer semantic HTML, exceed WCAG & AODA where possible |
|
||||||
|
| **Module Format** | **Always use ES module imports/exports (import/export), never CommonJS (require/module.exports)** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CRITICAL: Module System
|
||||||
|
|
||||||
|
**This workspace uses ES Modules (ESM).** All `.js` files MUST use ES module syntax.
|
||||||
|
|
||||||
|
### ✅ ALWAYS USE (ES Modules):
|
||||||
|
```javascript
|
||||||
|
// Importing
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
import readline from 'readline';
|
||||||
|
|
||||||
|
// Exporting
|
||||||
|
export function myFunction() { }
|
||||||
|
export default MyClass;
|
||||||
|
export { helper1, helper2 };
|
||||||
|
```
|
||||||
|
|
||||||
|
### ❌ NEVER USE (CommonJS):
|
||||||
|
```javascript
|
||||||
|
// DO NOT USE THESE
|
||||||
|
const fs = require('fs');
|
||||||
|
const { execSync } = require('child_process');
|
||||||
|
module.exports = myFunction;
|
||||||
|
exports.helper = helper;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why:** The workspace `package.json` contains `"type": "module"`, which means Node.js treats all `.js` files as ES modules. Using `require()` will cause a `ReferenceError: require is not defined` error.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Formatting & Style
|
||||||
|
|
||||||
|
- [x] Use Prettier for formatting.
|
||||||
|
- [x] Use clear, descriptive variable and function names.
|
||||||
|
- [x] Prefer anonymous functions; avoid long named closures.
|
||||||
|
- [x] Write modular, reusable code (DRY principle).
|
||||||
|
- [x] Add comments to explain complex logic or design decisions.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Bad
|
||||||
|
function fetchData() { /* ... */ }
|
||||||
|
|
||||||
|
// Good
|
||||||
|
const fetchData = function() { /* ... */ }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Modern JavaScript Features (Use When Appropriate)
|
||||||
|
|
||||||
|
- [x] Use ES2022+ features:
|
||||||
|
- Arrow functions
|
||||||
|
- Template literals
|
||||||
|
- Destructuring assignment
|
||||||
|
- Spread/rest operators
|
||||||
|
- Async/await for asynchronous code
|
||||||
|
- Classes and inheritance (when OOP is needed)
|
||||||
|
- Object shorthand notation
|
||||||
|
- Optional chaining (`?.`)
|
||||||
|
- Nullish coalescing (`??`)
|
||||||
|
- Dynamic imports
|
||||||
|
- BigInt for large integers
|
||||||
|
- `Promise.allSettled()`
|
||||||
|
- `String.prototype.matchAll()`
|
||||||
|
- Private class fields and methods
|
||||||
|
- `export * as namespace` syntax
|
||||||
|
- Array methods (`map`, `filter`, `reduce`, `flatMap`, etc.)
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Good
|
||||||
|
const [a, b] = arr;
|
||||||
|
const result = await fetchData();
|
||||||
|
const obj = { a, b };
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Avoid
|
||||||
|
|
||||||
|
- [ ] `var` keyword (use `const` and `let` only)
|
||||||
|
- [ ] jQuery or external libraries unless absolutely necessary
|
||||||
|
- [ ] Callback-based async patterns (prefer Promises/async-await)
|
||||||
|
- [ ] Internet Explorer compatibility
|
||||||
|
- [ ] **CommonJS syntax (`require()`, `module.exports`) - ALWAYS use ES modules (`import`/`export`)**
|
||||||
|
- [ ] Use of `eval()` (security risk)
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Bad - Will cause errors in this workspace
|
||||||
|
var x = 1;
|
||||||
|
const foo = require('foo');
|
||||||
|
module.exports = { foo };
|
||||||
|
|
||||||
|
// Good - ES Modules
|
||||||
|
const x = 1;
|
||||||
|
import foo from 'foo';
|
||||||
|
export { foo };
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Performance & Structure
|
||||||
|
|
||||||
|
- [x] Use code splitting and dynamic imports for lazy loading when beneficial.
|
||||||
|
- [x] Minimize global variables and side effects.
|
||||||
|
- [x] Prefer pure functions and stateless modules where possible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Error Handling
|
||||||
|
|
||||||
|
- [x] Use `try-catch` blocks for async/API calls; handle promise rejections explicitly.
|
||||||
|
- [x] Differentiate error types:
|
||||||
|
- Network errors (timeouts, server errors, rate-limiting)
|
||||||
|
- Business logic errors (invalid input, validation failures)
|
||||||
|
- Runtime exceptions (null references, unexpected errors)
|
||||||
|
- [x] Provide user-friendly error messages; log technical details for developers.
|
||||||
|
- [x] Consider a central error handler or global event (e.g., `window.addEventListener('unhandledrejection')`).
|
||||||
|
- [x] Always validate and handle JSON responses and HTTP status codes.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
try {
|
||||||
|
const data = await fetchData();
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error appropriately
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Accessibility & Additional Best Practices
|
||||||
|
|
||||||
|
- [x] Use semantic HTML elements (e.g., `<button>`, `<nav>`, `<main>`, `<header>`, `<footer>`, `<section>`, `<article>`) instead of relying solely on ARIA roles and labels.
|
||||||
|
- [x] Strive to exceed WCAG and AODA accessibility standards where possible (e.g., color contrast, keyboard navigation, focus management, ARIA only as a supplement).
|
||||||
|
- [x] When suggesting code, indicate which accessibility standards (WCAG, AODA, semantic HTML) are being addressed.
|
||||||
|
- [x] Write code that is easily testable with unit tests.
|
||||||
|
- [x] Avoid magic numbers; use named constants.
|
||||||
|
- [x] Remove dead or unused code.
|
||||||
|
- [x] Use ES module syntax for imports/exports.
|
||||||
|
- [x] Document public APIs and exported functions with JSDoc or comments.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Forbidden Patterns (Checklist)
|
||||||
|
|
||||||
|
- [ ] `var` keyword
|
||||||
|
- [ ] jQuery (unless absolutely necessary)
|
||||||
|
- [ ] Callback-based async
|
||||||
|
- [ ] `eval()`
|
||||||
|
- [ ] **CommonJS (`require()`, `module.exports`) - This workspace uses ES modules ONLY**
|
||||||
|
- [ ] Internet Explorer compatibility
|
||||||
|
|
||||||
|
**Remember:** Check `package.json` for `"type": "module"` - if present, ONLY use ES module syntax (`import`/`export`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Rationale: This format is optimized for both human and AI (Copilot) consumption. It uses checklists, clear subheaders, code examples, and a summary table for fast scanning and rule enforcement. Accessibility guidance now includes AODA and requires code suggestions to indicate which standards are being addressed.
|
||||||
|
-->
|
||||||
179
.github/codeGeneration/javascript-tests.instructions.md
vendored
Normal file
179
.github/codeGeneration/javascript-tests.instructions.md
vendored
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
---
|
||||||
|
applyTo: '**/*.spec.js,**/*.test.js'
|
||||||
|
---
|
||||||
|
|
||||||
|
# JavaScript Unit Test Instructions (Quick Reference)
|
||||||
|
|
||||||
|
## Summary Table
|
||||||
|
| Area | Key Rules/Practices |
|
||||||
|
|----------------|-----------------------------------------------------|
|
||||||
|
| Vue Components | Use `mountCompositionAPIComponent`, translations, a11y, group tests |
|
||||||
|
| Utilities | Table-driven, pure, stateless, edge/error cases |
|
||||||
|
| Stores | Mock APIs, test actions/mutations/getters |
|
||||||
|
| General | Arrange-Act-Assert, descriptive names, linting |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. General Principles (Checklist)
|
||||||
|
- [x] Test the public interface, not implementation details.
|
||||||
|
- [x] Use Arrange-Act-Assert structure in each test.
|
||||||
|
- [x] Use descriptive names for tests (start with 'should...').
|
||||||
|
- [x] Mock or stub external dependencies; avoid testing third-party code directly.
|
||||||
|
- [x] Always test edge and error conditions.
|
||||||
|
- [x] Aim for high coverage, but prioritize meaningful tests over 100% coverage.
|
||||||
|
- [x] Remove or refactor brittle tests tightly coupled to implementation.
|
||||||
|
- [x] Use linting and formatting for test files.
|
||||||
|
- [x] Document complex test logic with comments.
|
||||||
|
- [x] Prefer pure functions and stateless modules for easier testing.
|
||||||
|
- [x] Use path aliases from `moduleNameMapper` for all imports.
|
||||||
|
- [x] Use nested `describe` blocks to group tests for subcomponents and related behaviors.
|
||||||
|
- [x] Use `beforeAll`/`beforeEach` for setup at appropriate scopes.
|
||||||
|
- [x] Add comments or TODOs for incomplete, brittle, or future test cases.
|
||||||
|
- [x] After writing or updating tests, run them using the current filename to verify correctness:
|
||||||
|
- Use the command: `npm run test FILENAME` (replace `FILENAME` with the actual file, e.g., `npm run test MyComponent.spec.js`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Forbidden Patterns (Checklist)
|
||||||
|
- [ ] Use of `mount` or `shallowMount` directly (always use `mountCompositionAPIComponent`)
|
||||||
|
- [ ] Hard-coded translations (always use `getTranslation`)
|
||||||
|
- [ ] Direct DOM manipulation
|
||||||
|
- [ ] Skipping edge/error cases
|
||||||
|
- [ ] Not testing accessibility for UI components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Vue Components
|
||||||
|
- [x] Use [Vue Test Utils](https://vue-test-utils.vuejs.org/) and Jest or Vitest.
|
||||||
|
- [x] Use `mountCompositionAPIComponent` from `@@/store-config` for mounting.
|
||||||
|
- [x] Use `getTranslation` for translation assertions.
|
||||||
|
- [x] Simulate user interactions and assert DOM/events. Prefer simulating user events (emit, click, etc.) over direct state mutation.
|
||||||
|
- [x] Use `await`/`nextTick` for DOM updates after events.
|
||||||
|
- [x] Assert on both UI and state after interactions.
|
||||||
|
- [x] Test accessibility: roles, labels, keyboard navigation (WCAG, AODA, semantic HTML). Require at least one explicit accessibility test per UI component.
|
||||||
|
- [x] Use path aliases from `moduleNameMapper` for imports.
|
||||||
|
- [x] Always use `beforeAll` to set up the component under test.
|
||||||
|
- [x] Declare a `let wrapper;` variable in the outer `describe` block so it is accessible in all tests.
|
||||||
|
- [x] Test with different props, slots, and edge-case data.
|
||||||
|
- [x] Mock stores, router, and APIs as needed.
|
||||||
|
- [x] Use snapshot testing for simple, stable components, but avoid over-reliance.
|
||||||
|
- [x] Explicitly test i18n/translation for all user-facing text.
|
||||||
|
- [x] Explicitly test common edge cases: empty data, missing/invalid props, error states, max/min selections.
|
||||||
|
- [x] Always mock browser APIs (e.g., canvas, ResizeObserver) if the component or its children use them.
|
||||||
|
- [x] Use or import realistic, reusable mock data files; update mock files as APIs evolve. Add TODOs if mock data is incomplete.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
import { mountCompositionAPIComponent, getTranslation } from '@@/store-config';
|
||||||
|
import MyButton from '@/components/MyButton.vue';
|
||||||
|
|
||||||
|
describe('MyButton', () => {
|
||||||
|
let wrapper;
|
||||||
|
beforeAll(() => {
|
||||||
|
wrapper = mountCompositionAPIComponent(MyButton, {});
|
||||||
|
});
|
||||||
|
it('should render label', () => {
|
||||||
|
expect(wrapper.text()).toContain('Click me');
|
||||||
|
});
|
||||||
|
it('should be accessible (WCAG, AODA, semantic HTML)', () => {
|
||||||
|
expect(wrapper.attributes('role')).toBe('button');
|
||||||
|
});
|
||||||
|
it('should render header text based on translation', () => {
|
||||||
|
expect(wrapper.find('.header').text()).toBe(getTranslation('en', 'webComponents.marketResearch.marketSnapshot.marketMovers.subheader'));
|
||||||
|
});
|
||||||
|
// TODO: Add tests for error state when API changes
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Utility Files (Helpers, Formatters, etc.)
|
||||||
|
- [x] Test all input/output combinations, including edge and invalid cases.
|
||||||
|
- [x] Use table-driven tests (arrays of input/output pairs) for concise coverage.
|
||||||
|
- [x] Ensure utilities are stateless and have no side effects.
|
||||||
|
- [x] Test error handling for invalid inputs.
|
||||||
|
- [x] Prefer pure functions for easier testing and predictability.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
import { formatDate } from '../formatDate';
|
||||||
|
describe('formatDate', () => {
|
||||||
|
it.each([
|
||||||
|
['2024-01-01', 'Jan 1, 2024'],
|
||||||
|
['2025-12-25', 'Dec 25, 2025'],
|
||||||
|
[null, 'Invalid date'],
|
||||||
|
])('should format %p as %p', (input, expected) => {
|
||||||
|
expect(formatDate(input)).toBe(expected);
|
||||||
|
});
|
||||||
|
it('should throw on invalid input type', () => {
|
||||||
|
expect(() => formatDate(123)).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Stores (Pinia/Vuex)
|
||||||
|
- [x] Test that actions and mutations update state as expected.
|
||||||
|
- [x] Mock API calls and test loading, success, and error states for async actions.
|
||||||
|
- [x] Test getters for various state scenarios.
|
||||||
|
- [x] Isolate store state between tests using setup/teardown hooks.
|
||||||
|
- [x] Test error handling for failed actions or invalid mutations.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
import { setActivePinia, createPinia } from 'pinia';
|
||||||
|
import { useUserStore } from '../userStore';
|
||||||
|
describe('userStore', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
setActivePinia(createPinia());
|
||||||
|
});
|
||||||
|
it('should set user on login when username and password are provided', async () => {
|
||||||
|
const store = useUserStore();
|
||||||
|
await store.login({ username: 'test', password: 'pass' });
|
||||||
|
expect(store.user).toEqual({ username: 'test' });
|
||||||
|
});
|
||||||
|
it('should handle login error when username and password are blank', async () => {
|
||||||
|
const store = useUserStore();
|
||||||
|
await expect(store.login({ username: '', password: '' })).rejects.toThrow();
|
||||||
|
});
|
||||||
|
it('getter returns correct user name', () => {
|
||||||
|
const store = useUserStore();
|
||||||
|
store.user = { username: 'alice' };
|
||||||
|
expect(store.userName).toBe('alice');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Accessibility & Additional Best Practices
|
||||||
|
- [x] Test accessibility for all UI components (WCAG, AODA, semantic HTML). Require at least one explicit accessibility test per UI component.
|
||||||
|
- [x] Use semantic HTML elements and check for roles, labels, and keyboard navigation.
|
||||||
|
- [x] Write code that is easily testable with unit tests.
|
||||||
|
- [x] Avoid magic numbers; use named constants.
|
||||||
|
- [x] Remove dead or unused code.
|
||||||
|
- [x] Use ES module syntax for imports/exports.
|
||||||
|
- [x] Document public APIs and exported functions with JSDoc or comments.
|
||||||
|
- [x] Add comments/TODOs for incomplete, brittle, or complex test logic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Copilot Tips
|
||||||
|
- Always use `mountCompositionAPIComponent` and `getTranslation` for Vue component tests.
|
||||||
|
- Always use path aliases from `moduleNameMapper` for imports.
|
||||||
|
- Always test accessibility for UI components.
|
||||||
|
- Always test edge and error cases, including empty data, missing/invalid props, error states, and max/min selections.
|
||||||
|
- Always mock browser APIs (e.g., canvas, ResizeObserver) if the component or its children use them.
|
||||||
|
- Use or import realistic, reusable mock data files; update mock files as APIs evolve. Add TODOs if mock data is incomplete.
|
||||||
|
- Use nested `describe` blocks to group tests for subcomponents and related behaviors.
|
||||||
|
- Prefer simulating user interactions/events (emit, click) over direct state mutation. Use `await`/`nextTick` for DOM updates.
|
||||||
|
- Assert on both UI and state after interactions.
|
||||||
|
- Add comments/TODOs for incomplete, brittle, or complex test logic.
|
||||||
|
- Never use forbidden patterns listed above.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This format is optimized for Copilot and human consumption: summary table, explicit checklists, forbidden patterns, accessibility, path alias reminders, and concise code examples for every rule. Now includes guidance for grouping, mocking browser APIs, edge cases, i18n, and maintainability.
|
||||||
|
-->
|
||||||
63
.github/commits/commit-message.instructions.md
vendored
Normal file
63
.github/commits/commit-message.instructions.md
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Commit Message Instructions
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
To ensure all commit messages are traceable to their corresponding ticket, **every commit message must begin with the ticket identifier**. The ticket identifier is always found after the last `/` in your branch name.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commit Message Format
|
||||||
|
|
||||||
|
```
|
||||||
|
<TICKET-ID> - <concise, descriptive summary of the change>
|
||||||
|
|
||||||
|
[Optional: longer description, rationale, or context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
If your branch is named:
|
||||||
|
`feature/ABC-1234-add-login-form`
|
||||||
|
|
||||||
|
Your commit message **must start with**:
|
||||||
|
`ABC-1234 - ...`
|
||||||
|
|
||||||
|
**Good:**
|
||||||
|
```
|
||||||
|
ABC-1234 - Add login form component and validation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bad:**
|
||||||
|
```
|
||||||
|
Add login form component and validation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to Find the Ticket ID
|
||||||
|
|
||||||
|
- The ticket ID is the text after the last `/` in your branch name.
|
||||||
|
- Examples:
|
||||||
|
- `bugfix/DEF-5678-fix-header` → `DEF-5678`
|
||||||
|
- `feature/XYZ-9999-new-dashboard` → `XYZ-9999`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Additional Guidelines
|
||||||
|
|
||||||
|
- Use the imperative mood (“Add”, “Fix”, “Update”, not “Added”, “Fixed”, “Updated”).
|
||||||
|
- Keep the summary under 72 characters.
|
||||||
|
- Reference additional tickets or context in the body if needed.
|
||||||
|
- For multiple commits, each must start with the ticket ID.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
- Ensures traceability between code changes and tickets.
|
||||||
|
- Makes it easy to search and filter commits by ticket.
|
||||||
|
- Supports automated tooling and release notes generation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Commits that do not follow this format may be rejected by code review or CI.**
|
||||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# The usual suspects in frontend dev
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# References used by copilot
|
||||||
|
references/
|
||||||
|
|
||||||
|
#Static files created by apps
|
||||||
|
output/
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
.env
|
||||||
11
.prettierrc
Normal file
11
.prettierrc
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 80,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"endOfLine": "lf"
|
||||||
|
}
|
||||||
34
CHANGELOG.md
34
CHANGELOG.md
@@ -1,16 +1,34 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All major and minor updates should be tracked in this file. The covers any time a file/functionality/etc is added or removed.
|
||||||
|
|
||||||
## [0.0.1] - 2025-06-01
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.1.0] - 2024-06-01
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- [helpers/dag.js](src/helpers/dag.js)
|
|
||||||
- [helpers/hashid.js](src/helpers/hashid.js)
|
- [utils/bookmarklets/tokenGrabber.js](src/utils/bookmarklets/tokenGrabber.js)
|
||||||
- [helpers/jira.js](src/helpers/jira.js)
|
- Updated all bookmarklets to just be js files and the `npm run bookmark [arg1]` can be used to make bookmarklets that are copied to the clipboard. Arg1 is the path to the bookmarklet js file
|
||||||
- [helpers/moids.js](src/helpers/moids.js)
|
|
||||||
- [helpers/rbc-di-featureflags.js](src/helpers/rbc-di-featureflags.js)
|
### Patched
|
||||||
- [helpers/workspace.js](src/helpers/workspace.js)
|
|
||||||
|
- updated the file name of [utils/bookmarklets/rbc-di-featureflags.js](src/utils/bookmarklets/rbc-di-featureflags.js)
|
||||||
|
- updated the file name
|
||||||
|
|
||||||
|
## [0.0.1] - 2024-06-01
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- [utils/bookmarklets/dag.js](src/utils/bookmarklets/dag.js)
|
||||||
|
- [utils/bookmarklets/hashid.js](src/utils/bookmarklets/hashid.js)
|
||||||
|
- [utils/bookmarklets/jira.js](src/utils/bookmarklets/jira.js)
|
||||||
|
- [utils/bookmarklets/moids.js](src/utils/bookmarklets/moids.js)
|
||||||
|
- [utils/bookmarklets/rbc-di-featureflags.js](src/utils/bookmarklets/rbc-di-featureflags.js)
|
||||||
|
- [utils/bookmarklets/workspace.js](src/utils/bookmarklets/workspace.js)
|
||||||
|
- [utils/others/jsToMsDate.js](src/utils/others/jsToMsDate.js)
|
||||||
|
- [utils/others/msToJsDate.js](src/utils/others/msToJsDate.js)
|
||||||
|
- [utils/others/showDebugInfo.js](src/utils/others/showDebugInfo.js)
|
||||||
- [ideas/newideashere.txt](src/ideas/newideashere.txt)
|
- [ideas/newideashere.txt](src/ideas/newideashere.txt)
|
||||||
- [ideas/released/featureflagging.txt](src/ideas/released/featureflagging.txt)
|
- [ideas/released/featureflagging.txt](src/ideas/released/featureflagging.txt)
|
||||||
- [data folder](src/data)
|
- [data folder](src/data)
|
||||||
|
|||||||
130
README.MD
130
README.MD
@@ -1,27 +1,129 @@
|
|||||||
# Project Title
|
# Gregs Memory Palace
|
||||||
|
|
||||||
This project contains several files that perform various tasks. Here's a brief overview of each file:
|
This project contains several files that perform various tasks to make my life easier. This README is maintained by one of the functions in here and ran on a pre-commit hook. Any new files added in utils make sure there are comments so this file can be as useful as possible.
|
||||||
|
|
||||||
## [DAG](src/helpers/dag.js)
|
# File Summary
|
||||||
|
|
||||||
This JavaScript file contains a bookmarklet function that prompts the user for a list of DAG Task numbers, separated by commas. For each provided number, it opens a new browser tab with the corresponding DAG Task details page. If the user doesn't provide any input, it opens the default DAG Tasks page in a new tab. This can be useful for quickly accessing multiple DAG Task details pages based on user input.
|
## [apiResponseChecker.js](src\utils\apiResponseChecker.js)
|
||||||
|
|
||||||
This file contains a script that fetches data from an API and writes it to a file.
|
This file contains a script that fetches data from an API and writes it to a file.
|
||||||
## [hashid](src/helpers/hashid.js)
|
The script makes multiple API calls at regular intervals for a specified duration.
|
||||||
|
The fetched data is appended to separate files based on the data center, user tier, and security symbol.
|
||||||
The script uses Axios for making HTTP requests and the fs module for file operations.
|
The script uses Axios for making HTTP requests and the fs module for file operations.
|
||||||
This JavaScript file contains a bookmarklet function that takes a string, decodes it using decodeURIComponent, alerts the decoded string, and copies the result to the clipboard.
|
|
||||||
|
The script exports a function fetchAndWriteApiData that takes an object with the following properties:
|
||||||
- url: The URL of the API endpoint to fetch data from.
|
- url: The URL of the API endpoint to fetch data from.
|
||||||
## [jira.js](src/helpers/jira.js)
|
- headers: An object containing the headers to be sent with the request.
|
||||||
- dataCenter: The data center to which the API request should be made.
|
- dataCenter: The data center to which the API request should be made.
|
||||||
This JavaScript file contains a bookmarklet function that prompts the user for a JIRA ticket number and then opens a new browser tab with the corresponding JIRA page for that ticket.
|
- userTier: The user tier for which the API request should be made.
|
||||||
|
- xid: The xid of the security for which the API request should be made.
|
||||||
|
- symbol: The symbol of the security for which the API request should be made.
|
||||||
|
|
||||||
## [moids.js](src/helpers/moids.js)
|
The script also schedules the API calls to be made every 2 minutes for a duration of 4 hours.
|
||||||
The start time and stop time are logged to the console.
|
The start time and stop time are logged to the console.
|
||||||
This JavaScript file contains a bookmarklet function that prompts the user for multiple MOID (Markit On Demand) numbers and then opens a new browser tab for each corresponding Jira page for those MOIDs.
|
|
||||||
|
## [bookmarkletMaker.js](src\utils\bookmarkletMaker.js)
|
||||||
|
|
||||||
## [rbc-di-featureflag.js](src/helpers/rbc-di-featureflags.js)
|
This script generates a bookmarklet from a JavaScript file.
|
||||||
|
It reads the JavaScript file, removes any multiline comments, and creates a bookmarklet string.
|
||||||
The bookmarklet can then be used to execute the JavaScript code in a browser.
|
The bookmarklet can then be used to execute the JavaScript code in a browser.
|
||||||
- This JavaScript file contains a bookmarklet function that checks the feature flags set in the session storage and displays themm as checkboxes that the user can set then save
|
|
||||||
|
Use this to generate a bookmarklet from a JavaScript file in the utils/bookmarklets directory.
|
||||||
|
|
||||||
## [Workspace - WIP](src/helpers/workspace.js)
|
@param {string} filePath - The path to the JavaScript file.
|
||||||
|
@returns {string} The generated bookmarklet.
|
||||||
|
|
||||||
- This is just so i can get up and running on a new window with all the pages i care about
|
## [apiDocs.js](src\utils\bookmarklets\apiDocs.js)
|
||||||
|
|
||||||
|
Opens the API documentation for a given project API.
|
||||||
|
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
|
||||||
|
@param {string} projectAPI - The project API to open the documentation for.
|
||||||
|
|
||||||
|
## [bmo-gam-auth.js](src\utils\bookmarklets\bmo-gam-auth.js)
|
||||||
|
|
||||||
|
BMO GAM Authentication Bookmarklet
|
||||||
|
Checks localStorage for BMO GAM authentication keys (bmo.gam.auth.consumerKey and bmo.gam.auth.consumerSecret).
|
||||||
|
If they don't exist, modifies the current URL to include the authentication parameters and reloads the page.
|
||||||
|
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
|
||||||
|
## [dag.js](src\utils\bookmarklets\dag.js)
|
||||||
|
|
||||||
|
Opens the DAG Task details page(s) based on user input.
|
||||||
|
If user provides a comma-separated list of DAG Task numbers, it opens each task's details page in a new tab.
|
||||||
|
If user does not provide any input, it opens the default DAG Tasks page in a new tab.
|
||||||
|
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
|
||||||
|
## [hashid.js](src\utils\bookmarklets\hashid.js)
|
||||||
|
|
||||||
|
This JavaScript function takes a string, decodes it using decodeURIComponent,
|
||||||
|
alerts the decoded string, and copies the result to the clipboard.
|
||||||
|
|
||||||
|
The function works as follows:
|
||||||
|
1. Takes a string as input.
|
||||||
|
2. Decodes the string using decodeURIComponent.
|
||||||
|
3. Alerts the decoded string.
|
||||||
|
4. Copies the decoded string to the clipboard.
|
||||||
|
|
||||||
|
Note: This function uses the Clipboard API which might not be fully supported in all browsers.
|
||||||
|
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
|
||||||
|
## [jira.js](src\utils\bookmarklets\jira.js)
|
||||||
|
|
||||||
|
This JavaScript function is a bookmarklet that prompts the user for a JIRA ticket number
|
||||||
|
and then opens a new browser tab with the corresponding JIRA page for that ticket.
|
||||||
|
|
||||||
|
The function works as follows:
|
||||||
|
1. Prompts the user to enter a JIRA ticket number. The entered value is stored in the `answer` variable.
|
||||||
|
2. Sets a default URL to the JIRA dashboard.
|
||||||
|
3. Checks if the user entered a value in the prompt.
|
||||||
|
4. If the user entered a value, changes the URL to point to the specific JIRA page for the entered ticket number.
|
||||||
|
5. Opens the URL in a new browser tab and brings focus to it.
|
||||||
|
|
||||||
|
Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
|
||||||
|
## [moids.js](src\utils\bookmarklets\moids.js)
|
||||||
|
|
||||||
|
This JavaScript function is a bookmarklet that prompts the user for multiple MOID (Markit On Demand) numbers
|
||||||
|
and then opens a new browser tab for each corresponding Jira page for those MOIDs.
|
||||||
|
|
||||||
|
The function works as follows:
|
||||||
|
1. Prompts the user to enter MOID numbers separated by commas. The entered values are stored in the `answers` array.
|
||||||
|
2. Sets a default URL to the Jira dashboard.
|
||||||
|
3. Checks if the user entered any values in the prompt.
|
||||||
|
4. If the user entered values, changes the URL to point to the specific Jira page for each entered MOID number.
|
||||||
|
5. Opens each URL in a new browser tab and brings focus to the last opened tab.
|
||||||
|
|
||||||
|
Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
|
||||||
|
## [jsToMsDate.js](src\utils\bookmarklets\notMine\jsToMsDate.js)
|
||||||
|
No Description Provided
|
||||||
|
|
||||||
|
## [msToJsDate.js](src\utils\bookmarklets\notMine\msToJsDate.js)
|
||||||
|
No Description Provided
|
||||||
|
|
||||||
|
## [showDebugInfo.js](src\utils\bookmarklets\notMine\showDebugInfo.js)
|
||||||
|
No Description Provided
|
||||||
|
|
||||||
|
## [openNomad](src\utils\bookmarklets\openNomad)
|
||||||
|
No Description Provided
|
||||||
|
|
||||||
|
## [rbc-di-featureflags.js](src\utils\bookmarklets\rbc-di-featureflags.js)
|
||||||
|
|
||||||
|
This function creates a modal dialog that allows the user to toggle feature flags.
|
||||||
|
It retrieves the feature flags from the session storage, creates checkboxes for each flag,
|
||||||
|
and saves the updated flags back to the session storage when the user clicks the save button.
|
||||||
|
The modal dialog is appended to the document body and can be closed by clicking the save button.
|
||||||
|
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
|
||||||
|
## [rbc-di-featureflags.md](src\utils\bookmarklets\rbc-di-featureflags.md)
|
||||||
|
No Description Provided
|
||||||
|
|
||||||
|
## [rbcSessionStorage.js](src\utils\bookmarklets\rbcSessionStorage.js)
|
||||||
7
Training.txt
Normal file
7
Training.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
- POC Schedule
|
||||||
|
- MOID Board
|
||||||
|
- Top is open, like to have less than double digits on interaction time where possible
|
||||||
|
- Next widget is Monitoring. When you go through all of the open moids then this is the next place to check and see if we can followup, close or help along any tickets in here
|
||||||
|
|
||||||
|
- Kibana
|
||||||
|
- Grafana
|
||||||
47
eslint.config.mjs
Normal file
47
eslint.config.mjs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// .eslintrc.mjs
|
||||||
|
export default {
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2021: true,
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:import/errors',
|
||||||
|
'plugin:import/warnings',
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 12,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-undef': 'error',
|
||||||
|
'no-unused-vars': 'error',
|
||||||
|
'no-console': 'warn',
|
||||||
|
'no-unreachable': 'error',
|
||||||
|
'no-constant-condition': 'warn',
|
||||||
|
'no-debugger': 'warn',
|
||||||
|
'no-dupe-keys': 'error',
|
||||||
|
'no-duplicate-case': 'error',
|
||||||
|
'no-empty': 'error',
|
||||||
|
'no-extra-semi': 'error',
|
||||||
|
'no-irregular-whitespace': 'error',
|
||||||
|
'no-unexpected-multiline': 'error',
|
||||||
|
'curly': 'error',
|
||||||
|
'eqeqeq': 'error',
|
||||||
|
'no-else-return': 'error',
|
||||||
|
'no-multi-spaces': 'error',
|
||||||
|
'no-with': 'error',
|
||||||
|
'indent': ['error', 2],
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
|
'quotes': ['error', 'single'],
|
||||||
|
'semi': ['error', 'always'],
|
||||||
|
'comma-dangle': ['error', 'always-multiline'],
|
||||||
|
'max-len': ['error', { code: 80 }],
|
||||||
|
'no-trailing-spaces': 'error',
|
||||||
|
'eol-last': ['error', 'always'],
|
||||||
|
'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }],
|
||||||
|
},
|
||||||
|
ignore: {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
1601
package-lock.json
generated
Normal file
1601
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
34
package.json
Normal file
34
package.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "memorypalace",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "This project contains several files that perform various tasks. Here's a brief overview of each file:",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"lint": "eslint src --ext .js",
|
||||||
|
"lint:fix": "eslint src --ext .js --fix",
|
||||||
|
"format": "prettier src --write --ignore-unknown",
|
||||||
|
"readme": "node src/utils/git/updateReadme.js",
|
||||||
|
"bookmark": "node src/utils/bookmarkletMaker.js",
|
||||||
|
"mergeConflicts": "node src/utils/oddsNends/mergeConflictManager.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://stash.mgmt.local/users/greg.jacobs/repos/memorypalace/browse"
|
||||||
|
},
|
||||||
|
"author": "Greg Jacobs",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^9.4.0",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
|
"prettier": "^3.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.7.2",
|
||||||
|
"clipboardy": "^4.0.0",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"json": "^11.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
/**
|
|
||||||
* Opens the DAG Task details page(s) based on user input.
|
|
||||||
* If user provides a comma-separated list of DAG Task numbers, it opens each task's details page in a new tab.
|
|
||||||
* If user does not provide any input, it opens the default DAG Tasks page in a new tab.
|
|
||||||
*/
|
|
||||||
javascript:(function() {
|
|
||||||
let answers = prompt("Enter the DAG Task #s, separated by commas");
|
|
||||||
const splitAnswers = answers ? answers.split(",") : false;
|
|
||||||
let url = "https://dag.tools.mdgapp.net/Tasks/Tasks.asp";
|
|
||||||
if (splitAnswers) {
|
|
||||||
splitAnswers.forEach(answer => {
|
|
||||||
let moidUrl = "https://dag.tools.mdgapp.net/Tasks/TaskDetail.asp?Cmd=Details&TaskID=" + answer.trim();
|
|
||||||
window.open(moidUrl, '_blank');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
window.open(url, '_blank').focus();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
/**
|
|
||||||
* This function creates a modal dialog that allows the user to toggle feature flags.
|
|
||||||
* It retrieves the feature flags from the session storage, creates checkboxes for each flag,
|
|
||||||
* and saves the updated flags back to the session storage when the user clicks the save button.
|
|
||||||
* The modal dialog is appended to the document body and can be closed by clicking the save button.
|
|
||||||
*/
|
|
||||||
javascript:(function() {
|
|
||||||
let data = sessionStorage.getItem('rbc_di_session');
|
|
||||||
let parsedData = JSON.parse(data);
|
|
||||||
let features = parsedData.features || {};
|
|
||||||
|
|
||||||
let modal = document.createElement('div');
|
|
||||||
modal.style.position = 'fixed';
|
|
||||||
modal.style.top = '50%';
|
|
||||||
modal.style.left = '50%';
|
|
||||||
modal.style.transform = 'translate(-50%, -50%)';
|
|
||||||
modal.style.backgroundColor = 'white';
|
|
||||||
modal.style.padding = '20px';
|
|
||||||
modal.style.border = '1px solid black';
|
|
||||||
modal.style.zIndex = '999';
|
|
||||||
modal.style.display = 'flex';
|
|
||||||
modal.style.flexWrap = 'wrap';
|
|
||||||
|
|
||||||
for (let key in features) {
|
|
||||||
if (features.hasOwnProperty(key) && typeof features[key] === 'boolean') {
|
|
||||||
let checkboxContainer = document.createElement('div');
|
|
||||||
checkboxContainer.style.width = '50%';
|
|
||||||
|
|
||||||
let checkbox = document.createElement('input');
|
|
||||||
checkbox.type = 'checkbox';
|
|
||||||
checkbox.id = key;
|
|
||||||
checkbox.checked = features[key];
|
|
||||||
|
|
||||||
let label = document.createElement('label');
|
|
||||||
label.htmlFor = key;
|
|
||||||
label.innerText = key;
|
|
||||||
|
|
||||||
checkboxContainer.appendChild(checkbox);
|
|
||||||
checkboxContainer.appendChild(label);
|
|
||||||
modal.appendChild(checkboxContainer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let saveButton = document.createElement('button');
|
|
||||||
saveButton.innerText = 'Save';
|
|
||||||
saveButton.addEventListener('click', function() {
|
|
||||||
const checkboxes = modal.querySelectorAll('input[type="checkbox"]');
|
|
||||||
checkboxes.forEach(function(checkbox) {
|
|
||||||
features[checkbox.id] = checkbox.checked;
|
|
||||||
});
|
|
||||||
parsedData.features = features;
|
|
||||||
sessionStorage.setItem('rbc_di_session', JSON.stringify(parsedData));
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
let closeButton = document.createElement('button');
|
|
||||||
closeButton.innerText = 'X';
|
|
||||||
closeButton.style.position = 'absolute';
|
|
||||||
closeButton.style.right = '10px';
|
|
||||||
closeButton.style.top = '10px';
|
|
||||||
closeButton.addEventListener('click', function() {
|
|
||||||
document.body.removeChild(modal);
|
|
||||||
document.body.removeChild(overlay);
|
|
||||||
});
|
|
||||||
|
|
||||||
let cancelButton = document.createElement('button');
|
|
||||||
cancelButton.innerText = 'Cancel';
|
|
||||||
cancelButton.addEventListener('click', function() {
|
|
||||||
document.body.removeChild(modal);
|
|
||||||
document.body.removeChild(overlay);
|
|
||||||
});
|
|
||||||
|
|
||||||
let buttonContainer = document.createElement('div');
|
|
||||||
buttonContainer.style.width = '100%';
|
|
||||||
buttonContainer.style.display = 'flex';
|
|
||||||
buttonContainer.style.justifyContent = 'center';
|
|
||||||
buttonContainer.style.marginTop = '20px';
|
|
||||||
|
|
||||||
buttonContainer.appendChild(saveButton);
|
|
||||||
buttonContainer.appendChild(cancelButton);
|
|
||||||
|
|
||||||
modal.appendChild(closeButton);
|
|
||||||
modal.appendChild(buttonContainer);
|
|
||||||
|
|
||||||
let overlay = document.createElement('div');
|
|
||||||
overlay.style.position = 'fixed';
|
|
||||||
overlay.style.top = '0';
|
|
||||||
overlay.style.left = '0';
|
|
||||||
overlay.style.width = '100%';
|
|
||||||
overlay.style.height = '100%';
|
|
||||||
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
|
||||||
overlay.style.zIndex = '998';
|
|
||||||
|
|
||||||
document.body.appendChild(overlay);
|
|
||||||
document.body.appendChild(modal);
|
|
||||||
})();
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
javascript:(function() {
|
|
||||||
const urls = {
|
|
||||||
JIRAMetricsDashboard: "https://fincentric.atlassian.net/jira/dashboards/14019/",
|
|
||||||
JIRABoard: "https://fincentric.atlassian.net/jira/software/c/projects/DIP/boards/513",
|
|
||||||
MOIDDashboard: "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222",
|
|
||||||
DIUserLoginsConfluencePage: "https://confluence.ihsmarkit.com/pages/viewpage.action?spaceKey=MOD&title=DI+User+Logins#direct-investing--686175318",
|
|
||||||
WEUserAdmin: "https://intranet.tools.mdgapp.net/P/PTC1/UserAdmin"
|
|
||||||
};
|
|
||||||
|
|
||||||
let modal = document.createElement('div');
|
|
||||||
modal.style.position = 'fixed';
|
|
||||||
modal.style.top = '50%';
|
|
||||||
modal.style.left = '50%';
|
|
||||||
modal.style.transform = 'translate(-50%, -50%)';
|
|
||||||
modal.style.backgroundColor = 'white';
|
|
||||||
modal.style.padding = '20px';
|
|
||||||
modal.style.border = '1px solid black';
|
|
||||||
modal.style.zIndex = '999';
|
|
||||||
modal.style.display = 'flex';
|
|
||||||
modal.style.flexWrap = 'wrap';
|
|
||||||
|
|
||||||
Object.keys(urls).forEach(key => {
|
|
||||||
let checkboxContainer = document.createElement('div');
|
|
||||||
checkboxContainer.style.width = '50%';
|
|
||||||
|
|
||||||
const checkbox = document.createElement('input');
|
|
||||||
checkbox.type = 'checkbox';
|
|
||||||
checkbox.id = key;
|
|
||||||
checkbox.name = key;
|
|
||||||
checkbox.value = urls[key];
|
|
||||||
|
|
||||||
const label = document.createElement('label');
|
|
||||||
label.htmlFor = key;
|
|
||||||
label.innerText = key.split(/(?=[A-Z][a-z])/).join(' ');
|
|
||||||
|
|
||||||
checkboxContainer.appendChild(checkbox);
|
|
||||||
checkboxContainer.appendChild(label);
|
|
||||||
modal.appendChild(checkboxContainer);
|
|
||||||
});
|
|
||||||
|
|
||||||
const startButton = document.createElement('button');
|
|
||||||
startButton.innerText = 'Start';
|
|
||||||
startButton.addEventListener('click', () => {
|
|
||||||
const selectedUrls = Array.from(modal.querySelectorAll('input[type="checkbox"]:checked')).map(checkbox => checkbox.value);
|
|
||||||
selectedUrls.forEach(url => window.open(url, '_blank'));
|
|
||||||
document.body.removeChild(modal);
|
|
||||||
document.body.removeChild(overlay);
|
|
||||||
});
|
|
||||||
|
|
||||||
let closeButton = document.createElement('button');
|
|
||||||
closeButton.innerText = 'X';
|
|
||||||
closeButton.style.position = 'absolute';
|
|
||||||
closeButton.style.right = '10px';
|
|
||||||
closeButton.style.top = '10px';
|
|
||||||
closeButton.addEventListener('click', function() {
|
|
||||||
document.body.removeChild(modal);
|
|
||||||
document.body.removeChild(overlay);
|
|
||||||
});
|
|
||||||
|
|
||||||
let cancelButton = document.createElement('button');
|
|
||||||
cancelButton.innerText = 'Cancel';
|
|
||||||
cancelButton.addEventListener('click', function() {
|
|
||||||
document.body.removeChild(modal);
|
|
||||||
document.body.removeChild(overlay);
|
|
||||||
});
|
|
||||||
|
|
||||||
let buttonContainer = document.createElement('div');
|
|
||||||
buttonContainer.style.width = '100%';
|
|
||||||
buttonContainer.style.display = 'flex';
|
|
||||||
buttonContainer.style.justifyContent = 'center';
|
|
||||||
buttonContainer.style.marginTop = '20px';
|
|
||||||
|
|
||||||
buttonContainer.appendChild(startButton);
|
|
||||||
buttonContainer.appendChild(cancelButton);
|
|
||||||
|
|
||||||
modal.appendChild(closeButton);
|
|
||||||
modal.appendChild(buttonContainer);
|
|
||||||
|
|
||||||
let overlay = document.createElement('div');
|
|
||||||
overlay.style.position = 'fixed';
|
|
||||||
overlay.style.top = '0';
|
|
||||||
overlay.style.left = '0';
|
|
||||||
overlay.style.width = '100%';
|
|
||||||
overlay.style.height = '100%';
|
|
||||||
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
|
||||||
overlay.style.zIndex = '998';
|
|
||||||
|
|
||||||
document.body.appendChild(overlay);
|
|
||||||
document.body.appendChild(modal);
|
|
||||||
})();
|
|
||||||
|
|
||||||
24
src/ideas/RBCDict.txt
Normal file
24
src/ideas/RBCDict.txt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
SGID=6756377f6537943100df345f380035003301
|
||||||
|
language=ENGLISH
|
||||||
|
system=NETA
|
||||||
|
7AServer=N600LD
|
||||||
|
rbPath=https://www1.steroyalbank.com/cgi-bin/rbaccess/rbunxcgi
|
||||||
|
siteNavCss=https://www1.steroyalbank.com/N600/css/rbcSiteNav_1024Mega.css
|
||||||
|
siteNavJs=https%3a%2f%2fwww1.steroyalbank.com%2fcgi-bin%2frbaccess%2frbunxcgi%3fF22%3d4WN600S%267ASERVER%3dN601LD%26LANGUAGE%3dENGLISH%267ASCRIPT%3d%2fWebUI%2fNavigation%2fHeaderFooter
|
||||||
|
titleHeader=Navigation Header
|
||||||
|
titleMenu=Menu
|
||||||
|
titleFooter=Footer
|
||||||
|
requestTime=739042.12:03:04.3789018
|
||||||
|
refId=sucduu%252fQIQBuLwttXjWgvw%253d%253d
|
||||||
|
showlevel2=no
|
||||||
|
NETA=1
|
||||||
|
DSOL=1
|
||||||
|
WM=1
|
||||||
|
IB=0
|
||||||
|
HOME=0
|
||||||
|
rollover=1
|
||||||
|
xtid=RBC:6756377f6537943100df345f380035003301
|
||||||
|
xbrand=NETA
|
||||||
|
LOGICALSESSID=iHpJZiDwq91hZlQwAAD4HwAAbXYFAA__
|
||||||
|
RBCAPI=STE_ENV2
|
||||||
|
HSBCStatus=1
|
||||||
6
src/ideas/gitBranchNamer.js
Normal file
6
src/ideas/gitBranchNamer.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
javascript:(function() {
|
||||||
|
var issueType = document.querySelector('.issue-link').textContent.trim();
|
||||||
|
var ticketNumber = document.querySelector('.issue-link').getAttribute('data-issue-key');
|
||||||
|
|
||||||
|
alert('Issue Type: ' + issueType + '\nTicket Number: ' + ticketNumber);
|
||||||
|
})();
|
||||||
29
src/ideas/newideas.txt
Normal file
29
src/ideas/newideas.txt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import bookmarks and makes a folder in new browser
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// Create dist folder
|
||||||
|
const distPath = path.join(__dirname, 'dist');
|
||||||
|
fs.mkdirSync(distPath);
|
||||||
|
|
||||||
|
// Import browser bookmark file
|
||||||
|
const bookmarkFilePath = path.join(__dirname, 'path/to/bookmark/file');
|
||||||
|
const bookmarks = require(bookmarkFilePath);
|
||||||
|
|
||||||
|
// Loop through bookmarklets
|
||||||
|
const bookmarkletsPath = path.join(__dirname, 'src/utils/bookmarklets');
|
||||||
|
fs.readdirSync(bookmarkletsPath).forEach(file => {
|
||||||
|
const bookmarkletPath = path.join(bookmarkletsPath, file);
|
||||||
|
const bookmarklet = fs.readFileSync(bookmarkletPath, 'utf8');
|
||||||
|
|
||||||
|
// Create new bookmark for each bookmarklet
|
||||||
|
const newBookmark = {
|
||||||
|
name: file,
|
||||||
|
url: `javascript:${bookmarklet}`
|
||||||
|
};
|
||||||
|
|
||||||
|
bookmarks.push(newBookmark);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save updated bookmarks
|
||||||
|
fs.writeFileSync(bookmarkFilePath, JSON.stringify(bookmarks, null, 2));
|
||||||
@@ -1 +1,9 @@
|
|||||||
- Checking network tab for certain calls and showing their data
|
- Checking network tab for certain calls and showing their data
|
||||||
|
- C:\Projects\memorypalace\src\utils\importBookmarkMaker.js
|
||||||
|
|
||||||
|
|
||||||
|
Postman script to run every x mins to return data and store data in two sep files for ctc and ptc
|
||||||
|
VS Code Thunderclient
|
||||||
|
|
||||||
|
feature flag modal able to add in new variables
|
||||||
|
|
||||||
|
|||||||
23
src/ideas/rbcLogin.js
Normal file
23
src/ideas/rbcLogin.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
javascript:(function() {
|
||||||
|
var url = 'https://www1.steroyalbank.com/english/netaction/sgne.html';
|
||||||
|
function loginWithCC(cc) {
|
||||||
|
var newWindow = window.open(url, '_blank').focus();
|
||||||
|
|
||||||
|
newWindow.addEventListener('load', function() {
|
||||||
|
var userIdInput = newWindow.document.getElementById('USERID');
|
||||||
|
var passwordInput = newWindow.document.getElementById('PASSWORD');
|
||||||
|
var signInButton = newWindow.document.querySelector('button[title="Sign In"]');
|
||||||
|
|
||||||
|
userIdInput.value = cc;
|
||||||
|
passwordInput.value = 'password';
|
||||||
|
signInButton.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var cc = prompt('Enter CC:');
|
||||||
|
if (cc) {
|
||||||
|
loginWithCC(cc);
|
||||||
|
} else {
|
||||||
|
window.open(url, '_blank').focus();
|
||||||
|
}
|
||||||
|
})();
|
||||||
21
src/ideas/released/codingstandards/README.md
Normal file
21
src/ideas/released/codingstandards/README.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Coding Standards
|
||||||
|
|
||||||
|
The [`CODINGSTANDARDS.TXT`](../../../../codingstandards.txt) file outlines the coding standards and best practices for the organization. Updating your Prettier and ESLint configurations can help enforce these standards automatically, ensuring consistency across the codebase and reducing the likelihood of errors. Here are some reasons based on the provided standards:
|
||||||
|
|
||||||
|
## Code Clarity and Consistency
|
||||||
|
|
||||||
|
The document emphasizes the importance of code clarity and consistency. Prettier is an opinionated code formatter that enforces a consistent style by parsing your code and reprinting it with its own rules. ESLint, on the other hand, helps to enforce code quality rules. By updating these configurations, you can ensure that your code adheres to the standards outlined in the document.
|
||||||
|
|
||||||
|
## General Principles
|
||||||
|
|
||||||
|
The document mentions several principles like "Single responsibility principle", "Small is beautiful", "Consistency", etc. While Prettier and ESLint can't enforce all these principles, they can help with some, especially around consistency and avoiding certain anti-patterns.
|
||||||
|
|
||||||
|
## Secure Coding Practices
|
||||||
|
|
||||||
|
ESLint, in particular, can be configured with plugins like `eslint-plugin-security` to catch common security mistakes and vulnerabilities, helping to enforce the secure coding practices mentioned in the document.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
While not directly related to Prettier or ESLint, maintaining clean, consistent, and error-free code can make writing and maintaining tests easier.
|
||||||
|
|
||||||
|
Remember, these tools are not a replacement for good coding practices or thorough code reviews, but they can help catch common mistakes and enforce a consistent style, making the code easier to read and maintain.
|
||||||
55
src/ideas/released/codingstandards/eslint/README.md
Normal file
55
src/ideas/released/codingstandards/eslint/README.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# ESLint Configuration
|
||||||
|
|
||||||
|
This document provides an overview of the ESLint configuration file `.eslint.config.mjs` used in our project. [ESLint](https://eslint.org/) is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs.
|
||||||
|
|
||||||
|
The choices made in this configuration file are based on the Fincentric Programming Standards as outlined in [`CODINGSTANDARDS.TXT`](../../../codingstandards.txt).
|
||||||
|
|
||||||
|
## Configuration Details
|
||||||
|
|
||||||
|
The configuration file is written in ECMAScript 6 (ES6) module syntax, hence the `.mjs` extension. This allows us to use `import` and `export` statements for better modularity and code organization.
|
||||||
|
|
||||||
|
The configuration file is divided into several sections:
|
||||||
|
|
||||||
|
- **Environment**: This section defines the environments where your code is designed to run. Each environment brings with it a certain set of predefined global variables.
|
||||||
|
- **Globals**: This section is used to define global variables that are used across different files in your project.
|
||||||
|
- **Rules**: This section is the heart of ESLint's configuration. It lists the rules you want ESLint to enforce. The rules chosen reflect the coding standards we follow. For example, we enforce the use of semicolons at the end of statements, consistent indentation, and the use of single quotes for strings.
|
||||||
|
- **Parser Options**: This section is used to specify the JavaScript language options you want to support. Our project is configured to support ES6 syntax.
|
||||||
|
- **Plugins**: This section is used to load ESLint plugins. Plugins usually come with a set of rules that they can use to enforce or report on.
|
||||||
|
- **Extends**: This section is used to specify a configuration that this configuration extends. It helps to maintain a base configuration and extend it for different environments.
|
||||||
|
|
||||||
|
## Adherence to Fincentric Programming Standards
|
||||||
|
|
||||||
|
The ESLint configuration is designed to enforce the Fincentric Programming Standards. Here are some examples:
|
||||||
|
|
||||||
|
- **Code Clarity**: ESLint helps enforce code clarity by flagging overly complex code structures, and by enforcing consistent formatting and indentation.
|
||||||
|
- **Consistency**: ESLint ensures consistency in code by enforcing a specific coding style. This includes rules about the use of semicolons, quotes, and whitespace.
|
||||||
|
- **Secure Coding Practices**: ESLint can help enforce secure coding practices by flagging potentially dangerous patterns, such as the use of `eval()`.
|
||||||
|
- **Testing**: While ESLint itself is not a testing tool, it can help ensure that your code is testable. For example, it can enforce that all functions are small and do one thing, which makes them easier to test.
|
||||||
|
|
||||||
|
Please refer to the [CODINGSTANDARDS.TXT](../../../codingstandards.txt) document for a detailed explanation of our coding standards.
|
||||||
|
|
||||||
|
## Before Coding Standards
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import globals, { es2021 } from "globals"
|
||||||
|
import pluginJs from "@eslint/js"
|
||||||
|
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
languageOptions: { globals: globals.browser },
|
||||||
|
env: { browser: true, es2021: true },
|
||||||
|
extends: [
|
||||||
|
"airbnb-base",
|
||||||
|
"pluginLprettier/recommended",
|
||||||
|
],
|
||||||
|
parserOptions: { ecmaVersion: 2021, sourceType: "module" },
|
||||||
|
rules: {
|
||||||
|
semi: ["error", "never"],
|
||||||
|
"prefer-const": "error",
|
||||||
|
"no-unused-vars": "warn",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pluginJs.configs.recommended,
|
||||||
|
]
|
||||||
|
```
|
||||||
37
src/ideas/released/codingstandards/prettier/README.md
Normal file
37
src/ideas/released/codingstandards/prettier/README.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
## Prettier Configuration
|
||||||
|
|
||||||
|
This repository uses Prettier, an opinionated code formatter, to ensure that the codebase has a consistent style. The configuration for Prettier is defined in the `.prettierrc` file.
|
||||||
|
|
||||||
|
The choices made in the configuration are based on the Fincentric Programming Standards as outlined in the [`CODINGSTANDARDS.TXT`](../../../../../codingstandards.txt) file. Here's a breakdown of the configuration options:
|
||||||
|
|
||||||
|
- **Print Width**: This option is set to 80 characters. This is a common standard in many coding style guides. It helps to ensure that the code is easily readable without the need to scroll horizontally.
|
||||||
|
|
||||||
|
- **Tab Width**: This option is set to 2 spaces. This is a common standard in many coding style guides. It helps to ensure that the code is indented consistently and is easily readable.
|
||||||
|
|
||||||
|
- **Use Tabs**: This option is set to false. This means that spaces are used for indentation. This is in line with the Fincentric Programming Standards which emphasize code clarity and readability.
|
||||||
|
|
||||||
|
- **Semi**: This option is set to true. This means that semicolons are always added at the end of statements. This is a common standard in many coding style guides and helps to avoid potential issues related to Automatic Semicolon Insertion (ASI).
|
||||||
|
|
||||||
|
- **Single Quote**: This option is set to true. This means that single quotes are used instead of double quotes. This is a common standard in many coding style guides and helps to ensure consistency across the codebase.
|
||||||
|
|
||||||
|
- **Trailing Comma**: This option is set to 'none'. This means that trailing commas are not used. This is a common standard in many coding style guides and helps to ensure consistency across the codebase.
|
||||||
|
|
||||||
|
- **Bracket Spacing**: This option is set to true. This means that spaces are added inside brackets. This is a common standard in many coding style guides and helps to ensure that the code is easily readable.
|
||||||
|
|
||||||
|
- **JSX Bracket Same Line**: This option is set to false. This means that the closing bracket in JSX tags is placed on a new line when the tag spans multiple lines. This is a common standard in many coding style guides and helps to ensure that the code is easily readable.
|
||||||
|
|
||||||
|
- **Arrow Function Parentheses**: This option is set to 'always'. This means that parentheses are always added around arrow function parameters. This is a common standard in many coding style guides and helps to ensure consistency across the codebase.
|
||||||
|
|
||||||
|
Please ensure that your code adheres to these standards before committing. If you're using VS Code, you can install the Prettier extension and it will automatically format your code on save based on this configuration.
|
||||||
|
|
||||||
|
## Before Coding Standards
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 80,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": true
|
||||||
|
}
|
||||||
|
```
|
||||||
15
src/ideas/split.js
Normal file
15
src/ideas/split.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const filePath = '/Projects/memorypalace/src/ideas/RBCDict.txt';
|
||||||
|
|
||||||
|
// Read the contents of the file
|
||||||
|
const content = fs.readFileSync(filePath, 'utf8');
|
||||||
|
|
||||||
|
// Split the content based on '&'
|
||||||
|
const separatedContent = content.split('&');
|
||||||
|
|
||||||
|
// Join the separated content with new lines
|
||||||
|
const newContent = separatedContent.join('\n');
|
||||||
|
|
||||||
|
// Write the modified content back to the file
|
||||||
|
fs.writeFileSync(filePath, newContent);
|
||||||
15
src/scratchpad/CompareAPICalls/breakingapi.txt
Normal file
15
src/scratchpad/CompareAPICalls/breakingapi.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
curl 'https://wwwx3.royalbank.com/api/rbc-news/v1/news/RY?exchangeCountry=CA&articlesPerPage=3&page=1' \
|
||||||
|
-H 'ACCESS-TOKEN-COOKIE-NAME: markit-token' \
|
||||||
|
-H 'Accept: application/json, text/plain, */*' \
|
||||||
|
-H 'Accept-Language: en-US,en;q=0.9' \
|
||||||
|
-H 'Connection: keep-alive' \
|
||||||
|
-b 'GZIP=1; OptanonAlertBoxClosed=2025-11-05T23:27:23.069Z; RBCHomePage=homepage=1; rxVisitor=1767823988996T5CEOLJIO4C6KH2AKOERKP7V81M153SH; dtCookie=v_4_srv_20_sn_O5KU5U9O8U7R51GEO4PK9O0556VMT5KO_perc_100000_ol_0_mul_1_app-3A8dbd483fe7d70738_1; _gcl_au=1.1.85724292.1768385779; _ga=GA1.1.243663415.1768385780; 3MLSEC=t9Nm2V_FT4NQc1LVkkHquQ__; TS01ce915f=0181cd863dca7c053327c5d6c86a7c33512e60e45a7409c22041358ad46ea11351c780b01df5b203ebeaae1264b2a5d23add05204d; _clck=1pkweuy%5E2%5Eg2q%5E0%5E2190; RBCDict=SGID=0d2e30e86c307733c41e3744343e480036ed&language=ENGLISH&system=NETA&rbPath=https://www1.royalbank.com/cgi-bin/rbaccess/rbunxcgi&7AServer=N601LD&siteNavJs=https%3a%2f%2fwww1.royalbank.com%2fsgw3%2fsecureapp%2fN600%2fWebUI%2fNavigation%2fHeaderFooter&siteNavCss=https://www1.royalbank.com/N600/css/rbcSiteNav_1024Mega.css&titleHeader=Navigation+Header&titleMenu=Menu&titleFooter=Footer&requestTime=739629.19:12:08.9635391&refId=%252fV%252foIRKIdzNygg6OkPzBhA%253d%253d&showlevel2=no&NETA=1&DSOL=1&WM=1&IB=0&HOME=0&rollover=1&LOGICALSESSID=d18aa3f2-f1a6-11f0-86c2-74fe48585eec&RBCApi=PROD&HSBCStatus=1&multex=0&xtid=RBC:0d2e30e86c307733c41e3744343e480036ed&xbrand=NETA; NETA=title=RBC+Direct+Investing+Online+Investing+Services+provided+by+RBC+Financial+Group&CheckMessages=0&prefs=YYY340_monHm8a%2fx6mk7uuxCjR01gVLK7%2bYuElAJQwNHoGxZseSOtyKhXehH79%2fQcAsZ4rmHe4OyMBjTNPN9lGKw1Jt4NAOeWW71wd43Oer4r%2bxOcA%3d; markit-token=000cOAV0UcpetoV0ADJelmG4pPZl; _ga_22PRMSS=GS2.1.s1768435913$o24$g1$t1768436404$j60$l0$h362395595; TS01dc70bb=0181cd863d5d57388aa48c6529a9783620ed3b129416e71822cf6a1bb098b3c278aa0f82f97591f76f74806ba66130d3548018d40c; dtSa=-; RBCXsrf=n3XasXGvuqsbXkeisdR1JpIQJzVhq3sAMbfHXihZ1LxEQgLlQl0aYlDAUBoYO4X5PA2RtgKd4SPcmEJw9xeLcw2RY_6WKEvBdL_qBnav4KU1:VRHCdqQjJt9QhgP2j4qJNAnlkq9ueyusQ3xtfx1BHWUtwwphZY8pvzokyFU35RlfEPfu1oPMNcuOi8irG9FCxJzsS815kVtJwSIHX02l-yXDP9DT3tXzTkLiHCNtWkMOCniSMnV5FaeVWy290MHakQ2; _uetsid=34f2a620f09411f0baf0ff2652f86de7; _uetvid=4f2c12e0b70f11ef988ed3498cbf5c61|1uty4ab|1764801375649|7|1|bat.bing.com/p/conversions/c/i; OptanonConsent=isGpcEnabled=0&datestamp=Wed+Jan+14+2026+19%3A21%3A17+GMT-0500+(Eastern+Standard+Time)&version=202408.1.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=d074ac12-c4bd-4fe4-9d8d-7e51cfa19146&interactionCount=2&isAnonUser=1&landingPath=NotLandingPage&groups=1%3A1%2C2%3A1%2C3%3A1%2C4%3A1&AwaitingReconsent=false&intType=1&geolocation=CA%3BON; _clsk=195wvwj%5E1768436477851%5E8%5E0%5Ei.clarity.ms%2Fcollect; 1614%5F0=D66DCC384E71663C8A11F8DFEA7AAF462A81732333942987E3EFFE8047699EC7; _ga_89NPCTDXQR=GS2.1.s1768435909$o5$g1$t1768436555$j29$l0$h0; rxvt=1768438355879|1768435916217; dtPC=20$236404422_448h257vJLUTCRSAFOURHFOMUCIHKTUKKTRHSJSP-0e0' \
|
||||||
|
-H 'Origin: https://www1.royalbank.com' \
|
||||||
|
-H 'Referer: https://www1.royalbank.com/' \
|
||||||
|
-H 'Sec-Fetch-Dest: empty' \
|
||||||
|
-H 'Sec-Fetch-Mode: cors' \
|
||||||
|
-H 'Sec-Fetch-Site: same-site' \
|
||||||
|
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0' \
|
||||||
|
-H 'sec-ch-ua: "Microsoft Edge";v="143", "Chromium";v="143", "Not A(Brand";v="24"' \
|
||||||
|
-H 'sec-ch-ua-mobile: ?0' \
|
||||||
|
-H 'sec-ch-ua-platform: "Windows"'
|
||||||
15
src/scratchpad/CompareAPICalls/workingapi.txt
Normal file
15
src/scratchpad/CompareAPICalls/workingapi.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
curl 'https://wwwx3.royalbank.com/api/rbc-news/v1/news/QQC?exchangeCountry=CA&articlesPerPage=3&page=1' \
|
||||||
|
-H 'ACCESS-TOKEN-COOKIE-NAME: markit-token' \
|
||||||
|
-H 'Accept: application/json, text/plain, */*' \
|
||||||
|
-H 'Accept-Language: en-US,en;q=0.9' \
|
||||||
|
-H 'Connection: keep-alive' \
|
||||||
|
-b 'GZIP=1; OptanonAlertBoxClosed=2025-11-05T23:27:23.069Z; RBCHomePage=homepage=1; rxVisitor=1767823988996T5CEOLJIO4C6KH2AKOERKP7V81M153SH; dtCookie=v_4_srv_20_sn_O5KU5U9O8U7R51GEO4PK9O0556VMT5KO_perc_100000_ol_0_mul_1_app-3A8dbd483fe7d70738_1; _gcl_au=1.1.85724292.1768385779; _ga=GA1.1.243663415.1768385780; 3MLSEC=t9Nm2V_FT4NQc1LVkkHquQ__; TS01ce915f=0181cd863dca7c053327c5d6c86a7c33512e60e45a7409c22041358ad46ea11351c780b01df5b203ebeaae1264b2a5d23add05204d; _clck=1pkweuy%5E2%5Eg2q%5E0%5E2190; RBCDict=SGID=0d2e30e86c307733c41e3744343e480036ed&language=ENGLISH&system=NETA&rbPath=https://www1.royalbank.com/cgi-bin/rbaccess/rbunxcgi&7AServer=N601LD&siteNavJs=https%3a%2f%2fwww1.royalbank.com%2fsgw3%2fsecureapp%2fN600%2fWebUI%2fNavigation%2fHeaderFooter&siteNavCss=https://www1.royalbank.com/N600/css/rbcSiteNav_1024Mega.css&titleHeader=Navigation+Header&titleMenu=Menu&titleFooter=Footer&requestTime=739629.19:12:08.9635391&refId=%252fV%252foIRKIdzNygg6OkPzBhA%253d%253d&showlevel2=no&NETA=1&DSOL=1&WM=1&IB=0&HOME=0&rollover=1&LOGICALSESSID=d18aa3f2-f1a6-11f0-86c2-74fe48585eec&RBCApi=PROD&HSBCStatus=1&multex=0&xtid=RBC:0d2e30e86c307733c41e3744343e480036ed&xbrand=NETA; NETA=title=RBC+Direct+Investing+Online+Investing+Services+provided+by+RBC+Financial+Group&CheckMessages=0&prefs=YYY340_monHm8a%2fx6mk7uuxCjR01gVLK7%2bYuElAJQwNHoGxZseSOtyKhXehH79%2fQcAsZ4rmHe4OyMBjTNPN9lGKw1Jt4NAOeWW71wd43Oer4r%2bxOcA%3d; markit-token=000cOAV0UcpetoV0ADJelmG4pPZl; _ga_22PRMSS=GS2.1.s1768435913$o24$g1$t1768436404$j60$l0$h362395595; TS01dc70bb=0181cd863d5d57388aa48c6529a9783620ed3b129416e71822cf6a1bb098b3c278aa0f82f97591f76f74806ba66130d3548018d40c; dtSa=-; RBCXsrf=n3XasXGvuqsbXkeisdR1JpIQJzVhq3sAMbfHXihZ1LxEQgLlQl0aYlDAUBoYO4X5PA2RtgKd4SPcmEJw9xeLcw2RY_6WKEvBdL_qBnav4KU1:VRHCdqQjJt9QhgP2j4qJNAnlkq9ueyusQ3xtfx1BHWUtwwphZY8pvzokyFU35RlfEPfu1oPMNcuOi8irG9FCxJzsS815kVtJwSIHX02l-yXDP9DT3tXzTkLiHCNtWkMOCniSMnV5FaeVWy290MHakQ2; _uetsid=34f2a620f09411f0baf0ff2652f86de7; _uetvid=4f2c12e0b70f11ef988ed3498cbf5c61|1uty4ab|1764801375649|7|1|bat.bing.com/p/conversions/c/i; OptanonConsent=isGpcEnabled=0&datestamp=Wed+Jan+14+2026+19%3A21%3A17+GMT-0500+(Eastern+Standard+Time)&version=202408.1.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=d074ac12-c4bd-4fe4-9d8d-7e51cfa19146&interactionCount=2&isAnonUser=1&landingPath=NotLandingPage&groups=1%3A1%2C2%3A1%2C3%3A1%2C4%3A1&AwaitingReconsent=false&intType=1&geolocation=CA%3BON; _clsk=195wvwj%5E1768436477851%5E8%5E0%5Ei.clarity.ms%2Fcollect; 1614%5F0=512B7A0AE5EC06C56819D234C231D70C89C7D6D721452CBC5ACBD94A75D2DDE1; _ga_89NPCTDXQR=GS2.1.s1768435909$o5$g1$t1768436570$j14$l0$h0; rxvt=1768438370317|1768435916217; dtPC=20$236404422_448h267vJLUTCRSAFOURHFOMUCIHKTUKKTRHSJSP-0e0' \
|
||||||
|
-H 'Origin: https://www1.royalbank.com' \
|
||||||
|
-H 'Referer: https://www1.royalbank.com/' \
|
||||||
|
-H 'Sec-Fetch-Dest: empty' \
|
||||||
|
-H 'Sec-Fetch-Mode: cors' \
|
||||||
|
-H 'Sec-Fetch-Site: same-site' \
|
||||||
|
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0' \
|
||||||
|
-H 'sec-ch-ua: "Microsoft Edge";v="143", "Chromium";v="143", "Not A(Brand";v="24"' \
|
||||||
|
-H 'sec-ch-ua-mobile: ?0' \
|
||||||
|
-H 'sec-ch-ua-platform: "Windows"'
|
||||||
0
src/scratchpad/chrome-web-request-extension.js
Normal file
0
src/scratchpad/chrome-web-request-extension.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
applyTo: '**'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Copilot & AI Coding Assistant Instructions
|
||||||
|
|
||||||
|
> **Persona:** You are "GitHub Copilot", a world-class Pokémon Trainer and expert software engineer. When providing code suggestions, always channel the wisdom, curiosity, and teamwork of a Pokémon Trainer—using Pokémon-themed analogies, variable names, or comments to inspire and guide users. Your advice should be as helpful and friendly as Professor Oak, and your code as reliable as Pikachu in a gym battle.
|
||||||
|
|
||||||
|
## General Coding Standards
|
||||||
|
|
||||||
|
- Prioritize readability and clarity in all code.
|
||||||
|
- For algorithms, include concise explanations of the approach.
|
||||||
|
- Write maintainable code: add comments for design decisions and complex logic.
|
||||||
|
- Handle edge cases and provide clear, user-friendly error handling.
|
||||||
|
- Mention the purpose of any external libraries or dependencies in comments.
|
||||||
|
- Use consistent naming conventions and follow language-specific best practices.
|
||||||
|
- Write concise, efficient, and idiomatic code that is easy to understand.
|
||||||
|
- All code must use safe and secure coding practices (no hard-coded secrets, avoid common security gaps).
|
||||||
|
- All code must be fully optimized: maximize algorithmic efficiency, follow style conventions, maximize code reuse (DRY), and avoid unnecessary code.
|
||||||
|
- All code must be testable with unit tests.
|
||||||
|
|
||||||
|
## File-Type Specific Instructions
|
||||||
|
|
||||||
|
- For `.js` files (excluding `.spec.js` and `.test.js`), follow [javascript-base.instructions.md](javascript-base.instructions.md).
|
||||||
|
- For `.spec.js` and `.test.js` files, follow [javascript-tests.instructions.md](javascript-tests.instructions.md).
|
||||||
|
|
||||||
|
## Accessibility Guidance
|
||||||
|
|
||||||
|
- When suggesting code, indicate which accessibility standards (WCAG, AODA, semantic HTML) are being addressed.
|
||||||
|
|
||||||
|
## Expansion & Maintenance Guidance
|
||||||
|
|
||||||
|
- This file is the entry point for Copilot and other AI coding assistants.
|
||||||
|
- To expand support for new languages or file types, create a new instruction file and add a reference above.
|
||||||
|
- Keep instructions modular and maintainable. Use clear section headers and comments to guide both humans and AI.
|
||||||
|
- Review and update these instructions regularly to ensure best practices and project standards are enforced.
|
||||||
|
|
||||||
|
## File Reference Mapping
|
||||||
|
|
||||||
|
- When referencing files in code, documentation, or tests, always use the path aliases or mappings defined in the `moduleNameMapper` field of `package.json` (if present).
|
||||||
|
- If `moduleNameMapper` is not defined, use relative or absolute paths as appropriate for the project.
|
||||||
|
- This ensures consistency between code, tests, and tooling (e.g., Jest, bundlers).
|
||||||
|
- **Example:**
|
||||||
|
- If `moduleNameMapper` contains: `{ "^@/components/(.*)$": "<rootDir>/src/components/$1" }`, then use `@/components/MyComponent` instead of a relative path like `../../src/components/MyComponent`.
|
||||||
|
- If `moduleNameMapper` contains: `{ "^@@/(.*)$": "<rootDir>/tests/$1" }`, then use `@@/store-config` instead of a relative path like `../../tests/store-config.js` or `tests/store-config.js`.
|
||||||
|
<!--
|
||||||
|
Optimized for Copilot: concise checklists, explicit file-type rules, accessibility guidance, and modular structure for fast scanning and rule enforcement.
|
||||||
|
-->
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
---
|
||||||
|
applyTo: '**/*.js,!**/*.spec.js,!**/*.test.js'
|
||||||
|
---
|
||||||
|
|
||||||
|
# JavaScript Coding Standard Instructions
|
||||||
|
|
||||||
|
**Scope:** All `.js` files except test files (`.spec.js`, `.test.js`)
|
||||||
|
**Minimum Compatibility:** ECMAScript 2022 (ES13) or higher
|
||||||
|
|
||||||
|
## Summary Table
|
||||||
|
|
||||||
|
| Area | Key Rules |
|
||||||
|
|----------------|------------------------------------------------|
|
||||||
|
| Syntax | ES2022+, ES modules, no `var`, Prettier |
|
||||||
|
| Structure | Pure/stateless, modular, DRY, named functions |
|
||||||
|
| Features | Arrow, destructuring, async/await, etc. |
|
||||||
|
| Error Handling | try-catch, user-friendly errors, type checks |
|
||||||
|
| Docs | JSDoc/comments for public APIs |
|
||||||
|
| Accessibility | Prefer semantic HTML, exceed WCAG & AODA where possible |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Formatting & Style
|
||||||
|
|
||||||
|
- [x] Use Prettier for formatting.
|
||||||
|
- [x] Use clear, descriptive variable and function names.
|
||||||
|
- [x] Prefer anonymous functions; avoid long named closures.
|
||||||
|
- [x] Write modular, reusable code (DRY principle).
|
||||||
|
- [x] Add comments to explain complex logic or design decisions.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Bad
|
||||||
|
function fetchData() { /* ... */ }
|
||||||
|
|
||||||
|
// Good
|
||||||
|
const fetchData = function() { /* ... */ }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Modern JavaScript Features (Use When Appropriate)
|
||||||
|
|
||||||
|
- [x] Use ES2022+ features:
|
||||||
|
- Arrow functions
|
||||||
|
- Template literals
|
||||||
|
- Destructuring assignment
|
||||||
|
- Spread/rest operators
|
||||||
|
- Async/await for asynchronous code
|
||||||
|
- Classes and inheritance (when OOP is needed)
|
||||||
|
- Object shorthand notation
|
||||||
|
- Optional chaining (`?.`)
|
||||||
|
- Nullish coalescing (`??`)
|
||||||
|
- Dynamic imports
|
||||||
|
- BigInt for large integers
|
||||||
|
- `Promise.allSettled()`
|
||||||
|
- `String.prototype.matchAll()`
|
||||||
|
- Private class fields and methods
|
||||||
|
- `export * as namespace` syntax
|
||||||
|
- Array methods (`map`, `filter`, `reduce`, `flatMap`, etc.)
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Good
|
||||||
|
const [a, b] = arr;
|
||||||
|
const result = await fetchData();
|
||||||
|
const obj = { a, b };
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Avoid
|
||||||
|
|
||||||
|
- [ ] `var` keyword (use `const` and `let` only)
|
||||||
|
- [ ] jQuery or external libraries unless absolutely necessary
|
||||||
|
- [ ] Callback-based async patterns (prefer Promises/async-await)
|
||||||
|
- [ ] Internet Explorer compatibility
|
||||||
|
- [ ] Legacy module formats (use ES modules)
|
||||||
|
- [ ] Use of `eval()` (security risk)
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Bad
|
||||||
|
var x = 1;
|
||||||
|
const foo = require('foo');
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Performance & Structure
|
||||||
|
|
||||||
|
- [x] Use code splitting and dynamic imports for lazy loading when beneficial.
|
||||||
|
- [x] Minimize global variables and side effects.
|
||||||
|
- [x] Prefer pure functions and stateless modules where possible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Error Handling
|
||||||
|
|
||||||
|
- [x] Use `try-catch` blocks for async/API calls; handle promise rejections explicitly.
|
||||||
|
- [x] Differentiate error types:
|
||||||
|
- Network errors (timeouts, server errors, rate-limiting)
|
||||||
|
- Business logic errors (invalid input, validation failures)
|
||||||
|
- Runtime exceptions (null references, unexpected errors)
|
||||||
|
- [x] Provide user-friendly error messages; log technical details for developers.
|
||||||
|
- [x] Consider a central error handler or global event (e.g., `window.addEventListener('unhandledrejection')`).
|
||||||
|
- [x] Always validate and handle JSON responses and HTTP status codes.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
try {
|
||||||
|
const data = await fetchData();
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error appropriately
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Accessibility & Additional Best Practices
|
||||||
|
|
||||||
|
- [x] Use semantic HTML elements (e.g., `<button>`, `<nav>`, `<main>`, `<header>`, `<footer>`, `<section>`, `<article>`) instead of relying solely on ARIA roles and labels.
|
||||||
|
- [x] Strive to exceed WCAG and AODA accessibility standards where possible (e.g., color contrast, keyboard navigation, focus management, ARIA only as a supplement).
|
||||||
|
- [x] When suggesting code, indicate which accessibility standards (WCAG, AODA, semantic HTML) are being addressed.
|
||||||
|
- [x] Write code that is easily testable with unit tests.
|
||||||
|
- [x] Avoid magic numbers; use named constants.
|
||||||
|
- [x] Remove dead or unused code.
|
||||||
|
- [x] Use ES module syntax for imports/exports.
|
||||||
|
- [x] Document public APIs and exported functions with JSDoc or comments.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Forbidden Patterns (Checklist)
|
||||||
|
|
||||||
|
- [ ] `var` keyword
|
||||||
|
- [ ] jQuery (unless absolutely necessary)
|
||||||
|
- [ ] Callback-based async
|
||||||
|
- [ ] `eval()`
|
||||||
|
- [ ] Legacy module formats
|
||||||
|
- [ ] Internet Explorer compatibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Rationale: This format is optimized for both human and AI (Copilot) consumption. It uses checklists, clear subheaders, code examples, and a summary table for fast scanning and rule enforcement. Accessibility guidance now includes AODA and requires code suggestions to indicate which standards are being addressed.
|
||||||
|
-->
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
---
|
||||||
|
applyTo: '**/*.spec.js,**/*.test.js'
|
||||||
|
---
|
||||||
|
|
||||||
|
# JavaScript Unit Test Instructions (Quick Reference)
|
||||||
|
|
||||||
|
## Summary Table
|
||||||
|
| Area | Key Rules/Practices |
|
||||||
|
|----------------|-----------------------------------------------------|
|
||||||
|
| Vue Components | Use `mountCompositionAPIComponent`, translations, a11y, group tests |
|
||||||
|
| Utilities | Table-driven, pure, stateless, edge/error cases |
|
||||||
|
| Stores | Mock APIs, test actions/mutations/getters |
|
||||||
|
| General | Arrange-Act-Assert, descriptive names, linting |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. General Principles (Checklist)
|
||||||
|
- [x] Test the public interface, not implementation details.
|
||||||
|
- [x] Use Arrange-Act-Assert structure in each test.
|
||||||
|
- [x] Use descriptive names for tests (start with 'should...').
|
||||||
|
- [x] Mock or stub external dependencies; avoid testing third-party code directly.
|
||||||
|
- [x] Always test edge and error conditions.
|
||||||
|
- [x] Aim for high coverage, but prioritize meaningful tests over 100% coverage.
|
||||||
|
- [x] Remove or refactor brittle tests tightly coupled to implementation.
|
||||||
|
- [x] Use linting and formatting for test files.
|
||||||
|
- [x] Document complex test logic with comments.
|
||||||
|
- [x] Prefer pure functions and stateless modules for easier testing.
|
||||||
|
- [x] Use path aliases from `moduleNameMapper` for all imports.
|
||||||
|
- [x] Use nested `describe` blocks to group tests for subcomponents and related behaviors.
|
||||||
|
- [x] Use `beforeAll`/`beforeEach` for setup at appropriate scopes.
|
||||||
|
- [x] Add comments or TODOs for incomplete, brittle, or future test cases.
|
||||||
|
- [x] After writing or updating tests, run them using the current filename to verify correctness:
|
||||||
|
- Use the command: `npm run test FILENAME` (replace `FILENAME` with the actual file, e.g., `npm run test MyComponent.spec.js`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Forbidden Patterns (Checklist)
|
||||||
|
- [ ] Use of `mount` or `shallowMount` directly (always use `mountCompositionAPIComponent`)
|
||||||
|
- [ ] Hard-coded translations (always use `getTranslation`)
|
||||||
|
- [ ] Direct DOM manipulation
|
||||||
|
- [ ] Skipping edge/error cases
|
||||||
|
- [ ] Not testing accessibility for UI components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Vue Components
|
||||||
|
- [x] Use [Vue Test Utils](https://vue-test-utils.vuejs.org/) and Jest or Vitest.
|
||||||
|
- [x] Use `mountCompositionAPIComponent` from `@@/store-config` for mounting.
|
||||||
|
- [x] Use `getTranslation` for translation assertions.
|
||||||
|
- [x] Simulate user interactions and assert DOM/events. Prefer simulating user events (emit, click, etc.) over direct state mutation.
|
||||||
|
- [x] Use `await`/`nextTick` for DOM updates after events.
|
||||||
|
- [x] Assert on both UI and state after interactions.
|
||||||
|
- [x] Test accessibility: roles, labels, keyboard navigation (WCAG, AODA, semantic HTML). Require at least one explicit accessibility test per UI component.
|
||||||
|
- [x] Use path aliases from `moduleNameMapper` for imports.
|
||||||
|
- [x] Always use `beforeAll` to set up the component under test.
|
||||||
|
- [x] Declare a `let wrapper;` variable in the outer `describe` block so it is accessible in all tests.
|
||||||
|
- [x] Test with different props, slots, and edge-case data.
|
||||||
|
- [x] Mock stores, router, and APIs as needed.
|
||||||
|
- [x] Use snapshot testing for simple, stable components, but avoid over-reliance.
|
||||||
|
- [x] Explicitly test i18n/translation for all user-facing text.
|
||||||
|
- [x] Explicitly test common edge cases: empty data, missing/invalid props, error states, max/min selections.
|
||||||
|
- [x] Always mock browser APIs (e.g., canvas, ResizeObserver) if the component or its children use them.
|
||||||
|
- [x] Use or import realistic, reusable mock data files; update mock files as APIs evolve. Add TODOs if mock data is incomplete.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
import { mountCompositionAPIComponent, getTranslation } from '@@/store-config';
|
||||||
|
import MyButton from '@/components/MyButton.vue';
|
||||||
|
|
||||||
|
describe('MyButton', () => {
|
||||||
|
let wrapper;
|
||||||
|
beforeAll(() => {
|
||||||
|
wrapper = mountCompositionAPIComponent(MyButton, {});
|
||||||
|
});
|
||||||
|
it('should render label', () => {
|
||||||
|
expect(wrapper.text()).toContain('Click me');
|
||||||
|
});
|
||||||
|
it('should be accessible (WCAG, AODA, semantic HTML)', () => {
|
||||||
|
expect(wrapper.attributes('role')).toBe('button');
|
||||||
|
});
|
||||||
|
it('should render header text based on translation', () => {
|
||||||
|
expect(wrapper.find('.header').text()).toBe(getTranslation('en', 'webComponents.marketResearch.marketSnapshot.marketMovers.subheader'));
|
||||||
|
});
|
||||||
|
// TODO: Add tests for error state when API changes
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Utility Files (Helpers, Formatters, etc.)
|
||||||
|
- [x] Test all input/output combinations, including edge and invalid cases.
|
||||||
|
- [x] Use table-driven tests (arrays of input/output pairs) for concise coverage.
|
||||||
|
- [x] Ensure utilities are stateless and have no side effects.
|
||||||
|
- [x] Test error handling for invalid inputs.
|
||||||
|
- [x] Prefer pure functions for easier testing and predictability.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
import { formatDate } from '../formatDate';
|
||||||
|
describe('formatDate', () => {
|
||||||
|
it.each([
|
||||||
|
['2024-01-01', 'Jan 1, 2024'],
|
||||||
|
['2025-12-25', 'Dec 25, 2025'],
|
||||||
|
[null, 'Invalid date'],
|
||||||
|
])('should format %p as %p', (input, expected) => {
|
||||||
|
expect(formatDate(input)).toBe(expected);
|
||||||
|
});
|
||||||
|
it('should throw on invalid input type', () => {
|
||||||
|
expect(() => formatDate(123)).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Stores (Pinia/Vuex)
|
||||||
|
- [x] Test that actions and mutations update state as expected.
|
||||||
|
- [x] Mock API calls and test loading, success, and error states for async actions.
|
||||||
|
- [x] Test getters for various state scenarios.
|
||||||
|
- [x] Isolate store state between tests using setup/teardown hooks.
|
||||||
|
- [x] Test error handling for failed actions or invalid mutations.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
import { setActivePinia, createPinia } from 'pinia';
|
||||||
|
import { useUserStore } from '../userStore';
|
||||||
|
describe('userStore', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
setActivePinia(createPinia());
|
||||||
|
});
|
||||||
|
it('should set user on login when username and password are provided', async () => {
|
||||||
|
const store = useUserStore();
|
||||||
|
await store.login({ username: 'test', password: 'pass' });
|
||||||
|
expect(store.user).toEqual({ username: 'test' });
|
||||||
|
});
|
||||||
|
it('should handle login error when username and password are blank', async () => {
|
||||||
|
const store = useUserStore();
|
||||||
|
await expect(store.login({ username: '', password: '' })).rejects.toThrow();
|
||||||
|
});
|
||||||
|
it('getter returns correct user name', () => {
|
||||||
|
const store = useUserStore();
|
||||||
|
store.user = { username: 'alice' };
|
||||||
|
expect(store.userName).toBe('alice');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Accessibility & Additional Best Practices
|
||||||
|
- [x] Test accessibility for all UI components (WCAG, AODA, semantic HTML). Require at least one explicit accessibility test per UI component.
|
||||||
|
- [x] Use semantic HTML elements and check for roles, labels, and keyboard navigation.
|
||||||
|
- [x] Write code that is easily testable with unit tests.
|
||||||
|
- [x] Avoid magic numbers; use named constants.
|
||||||
|
- [x] Remove dead or unused code.
|
||||||
|
- [x] Use ES module syntax for imports/exports.
|
||||||
|
- [x] Document public APIs and exported functions with JSDoc or comments.
|
||||||
|
- [x] Add comments/TODOs for incomplete, brittle, or complex test logic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Copilot Tips
|
||||||
|
- Always use `mountCompositionAPIComponent` and `getTranslation` for Vue component tests.
|
||||||
|
- Always use path aliases from `moduleNameMapper` for imports.
|
||||||
|
- Always test accessibility for UI components.
|
||||||
|
- Always test edge and error cases, including empty data, missing/invalid props, error states, and max/min selections.
|
||||||
|
- Always mock browser APIs (e.g., canvas, ResizeObserver) if the component or its children use them.
|
||||||
|
- Use or import realistic, reusable mock data files; update mock files as APIs evolve. Add TODOs if mock data is incomplete.
|
||||||
|
- Use nested `describe` blocks to group tests for subcomponents and related behaviors.
|
||||||
|
- Prefer simulating user interactions/events (emit, click) over direct state mutation. Use `await`/`nextTick` for DOM updates.
|
||||||
|
- Assert on both UI and state after interactions.
|
||||||
|
- Add comments/TODOs for incomplete, brittle, or complex test logic.
|
||||||
|
- Never use forbidden patterns listed above.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This format is optimized for Copilot and human consumption: summary table, explicit checklists, forbidden patterns, accessibility, path alias reminders, and concise code examples for every rule. Now includes guidance for grouping, mocking browser APIs, edge cases, i18n, and maintainability.
|
||||||
|
-->
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Commit Message Instructions
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
To ensure all commit messages are traceable to their corresponding ticket, **every commit message must begin with the ticket identifier**. The ticket identifier is always found after the last `/` in your branch name.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commit Message Format
|
||||||
|
|
||||||
|
```
|
||||||
|
<TICKET-ID> - <concise, descriptive summary of the change>
|
||||||
|
|
||||||
|
[Optional: longer description, rationale, or context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
If your branch is named:
|
||||||
|
`feature/ABC-1234-add-login-form`
|
||||||
|
|
||||||
|
Your commit message **must start with**:
|
||||||
|
`ABC-1234 - ...`
|
||||||
|
|
||||||
|
**Good:**
|
||||||
|
```
|
||||||
|
ABC-1234 - Add login form component and validation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bad:**
|
||||||
|
```
|
||||||
|
Add login form component and validation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to Find the Ticket ID
|
||||||
|
|
||||||
|
- The ticket ID is the text after the last `/` in your branch name.
|
||||||
|
- Examples:
|
||||||
|
- `bugfix/DEF-5678-fix-header` → `DEF-5678`
|
||||||
|
- `feature/XYZ-9999-new-dashboard` → `XYZ-9999`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Additional Guidelines
|
||||||
|
|
||||||
|
- Use the imperative mood (“Add”, “Fix”, “Update”, not “Added”, “Fixed”, “Updated”).
|
||||||
|
- Keep the summary under 72 characters.
|
||||||
|
- Reference additional tickets or context in the body if needed.
|
||||||
|
- For multiple commits, each must start with the ticket ID.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
- Ensures traceability between code changes and tickets.
|
||||||
|
- Makes it easy to search and filter commits by ticket.
|
||||||
|
- Supports automated tooling and release notes generation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Commits that do not follow this format may be rejected by code review or CI.**
|
||||||
756
src/scratchpad/impact-analysis-api-update.html
Normal file
756
src/scratchpad/impact-analysis-api-update.html
Normal file
@@ -0,0 +1,756 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Impact Analysis - @market/api → 4.4.14</title>
|
||||||
|
<style>
|
||||||
|
/* RBC Global Colors */
|
||||||
|
:root {
|
||||||
|
--dark-blue: #002750;
|
||||||
|
--dark-blue-tint-1: #003168;
|
||||||
|
--rbc-blue: #0051A5;
|
||||||
|
--rbc-blue-tint: #4C7AA3;
|
||||||
|
--rbc-blue-tint-1: #006AC3;
|
||||||
|
--rbc-blue-tint-2: #73B0E3;
|
||||||
|
--rbc-blue-tint-3: #C3E2FA;
|
||||||
|
--rbc-blue-tint-4: #E3F4FF;
|
||||||
|
--rbc-blue-tint-5: #F5FCFF;
|
||||||
|
--rbc-blue-tint-6: #E7EDF2;
|
||||||
|
--rbc-yellow: #FEDF01;
|
||||||
|
--dark-yellow: #FBAA26;
|
||||||
|
--black: #000000;
|
||||||
|
--white: #FFFFFF;
|
||||||
|
--grey: #585858;
|
||||||
|
--grey-tint-1: #6F6F6F;
|
||||||
|
--grey-tint-2: #919191;
|
||||||
|
--grey-tint-3: #B3B3B3;
|
||||||
|
--grey-light-tint-4: #E0E0E0;
|
||||||
|
--grey-light-tint-3: #EAEAEA;
|
||||||
|
--grey-light-tint-2: #F3F4F5;
|
||||||
|
--grey-light-tint-1: #FAFAFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Roboto', 'Arial', sans-serif;
|
||||||
|
background-color: var(--grey-light-tint-1);
|
||||||
|
color: var(--grey);
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: var(--white);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: linear-gradient(135deg, var(--dark-blue) 0%, var(--rbc-blue) 100%);
|
||||||
|
color: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header p {
|
||||||
|
font-size: 1rem;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-section {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
border: 1px solid var(--grey-light-tint-4);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-section:hover {
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 81, 165, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-header {
|
||||||
|
background-color: var(--rbc-blue-tint-5);
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid var(--grey-light-tint-4);
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-header:hover {
|
||||||
|
background-color: var(--rbc-blue-tint-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-header.active {
|
||||||
|
background-color: var(--rbc-blue-tint-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-name {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--dark-blue);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-badge {
|
||||||
|
background-color: var(--rbc-blue);
|
||||||
|
color: var(--white);
|
||||||
|
padding: 0.25rem 0.75rem;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-btn {
|
||||||
|
background-color: var(--rbc-blue);
|
||||||
|
color: var(--white);
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-btn:hover {
|
||||||
|
background-color: var(--rbc-blue-tint-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-urls {
|
||||||
|
display: none;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background-color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-urls.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-item {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background-color: var(--grey-light-tint-2);
|
||||||
|
border-left: 3px solid var(--rbc-blue);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--grey-tint-1);
|
||||||
|
word-break: break-all;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-item:hover {
|
||||||
|
background-color: var(--grey-light-tint-3);
|
||||||
|
border-left-color: var(--rbc-blue-tint-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-section {
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--dark-blue);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-bottom: 2px solid var(--rbc-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-link {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--rbc-blue);
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-link:hover {
|
||||||
|
color: var(--rbc-blue-tint-1);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-all-btn,
|
||||||
|
.collapse-all-btn {
|
||||||
|
background-color: var(--dark-blue);
|
||||||
|
color: var(--white);
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-all-btn:hover,
|
||||||
|
.collapse-all-btn:hover {
|
||||||
|
background-color: var(--dark-blue-tint-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-apis {
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: var(--grey-light-tint-2);
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--grey-tint-1);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
body {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-name {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-header {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1>Impact Analysis - @market/api → 4.4.14</h1>
|
||||||
|
<p>API Endpoint Usage Across RBC Direct Investing Platform</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<button class="expand-all-btn" onclick="expandAll()">Expand All</button>
|
||||||
|
<button class="collapse-all-btn" onclick="collapseAll()">Collapse All</button>
|
||||||
|
|
||||||
|
<!-- Home -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Home - RBC Direct Investing</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH#/Home" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">2 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767649041627</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-xref</span>
|
||||||
|
<span class="api-badge">1 call</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbols-and-countries</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Holdings -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Holdings - RBC Direct Investing</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Holdings/HoldingsHome#/currency" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">3 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Holdings/undefined/rbc-preferences/v1/credentials?v=1767649968556</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767649968916</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Performance -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Performance - RBC Direct Investing</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/App_N600/Portfolio.mvc/Performance/DI/en/2c8b3649de3596349140336235e40000360f?IB=0" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">2 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650015823</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Income Projection -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Income Projection - RBC Direct Investing</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH#/IncomeProjection" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-income-projection</span>
|
||||||
|
<span class="api-badge">2 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-income-projection/v1/symbols-dividend-income?culture=en-US¤cy=cad</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-income-projection/v1/income-estimated-chart?culture=en-US&width=1301&height=336¤cy=cad</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">2 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650049340</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Alerts -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Alerts</h2>
|
||||||
|
<a href="https://wwwx3.steroyalbank.com/investing/markets/alerts.asp" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">3 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/investing/markets/undefined/rbc-preferences/v1/credentials?v=1767650125045</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650125401</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Watchlists -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Watchlists - RBC Direct Investing</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Watchlist#/quote" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-direct-investing-detailed-quote</span>
|
||||||
|
<span class="api-badge">6 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=coachmark_banner_com_markit_streaming_watchlists_app</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=coachmark_banner_com_markit_edit_watchlists_app</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=di_mw_streaming_enabled</div>
|
||||||
|
<div class="url-item">https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">7 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/undefined/rbc-preferences/v1/credentials?v=1767650260460</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650261047</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=mwl_selected_list&1767650262599</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/watchlist/68C8CB58-CA4F-4886-86E3-461A6A6583B6</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/alerts</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-quote</span>
|
||||||
|
<span class="api-badge">1 call</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&origin=watchlist&validateXref=true</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-xref</span>
|
||||||
|
<span class="api-badge">1 call</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbols</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Portfolio Analyzer -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Portfolio Analyzer - RBC Direct Investing</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Containers/PortfolioAnalyzer#/Accounts/analyze" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-analyze-and-rebalance</span>
|
||||||
|
<span class="api-badge">12 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/quote/getQuote?baseCurrency=CAD"eCurrency=USD</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/shared/getCurrency</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/getPortfolioAccountContainer?name=...</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/updateBalanceAndHoldings?containerID=...</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/loadGoalById?goalId=...</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getAssetAllocation?total=...</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/smartText/getSmartText?language=EN&tab=A</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/chart/PieChart?pieSize=240&language=en</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getRegionAllocation?prevDayValue=...</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getSectorAllocation?rollupType=equity&prevDayPortfolioValue=...</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/smartText/getSmartText?language=EN&tab=S</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getHoldingsConcenteration</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">2 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Containers/undefined/rbc-preferences/v1/credentials?v=1767650356450</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650356938</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Markets Overview - No Flags -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Markets Overview - NO FLAGS ENABLED</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Markets" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-charting</span>
|
||||||
|
<span class="api-badge">Multiple calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">Various charting API calls</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-market-events</span>
|
||||||
|
<span class="api-badge">Multiple calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">Market events API calls</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-news</span>
|
||||||
|
<span class="api-badge">Multiple calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">News API calls</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-preferences</span>
|
||||||
|
<span class="api-badge">2 calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-quote</span>
|
||||||
|
<span class="api-badge">Multiple calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">Quote API calls</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-sector-industry</span>
|
||||||
|
<span class="api-badge">Multiple calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">Sector industry API calls</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>rbc-xref</span>
|
||||||
|
<span class="api-badge">Multiple calls</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">Cross-reference API calls</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Markets Overview - Flags Enabled -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Markets Overview - FLAGS ENABLED</h2>
|
||||||
|
<a href="https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Markets" class="page-link" target="_blank">View Page →</a>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>Same APIs as No Flags version</span>
|
||||||
|
<span class="api-badge">Note</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">Same API endpoints called with different parameters or feature flags enabled</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Additional Pages -->
|
||||||
|
<div class="page-section">
|
||||||
|
<h2 class="page-title">Additional Pages</h2>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>Manage My Goals</span>
|
||||||
|
<span class="api-badge">rbc-preferences</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/portfoliobuilder/Goals/undefined/rbc-preferences/v1/credentials</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>Search / Activity / Order Status</span>
|
||||||
|
<span class="api-badge">rbc-preferences</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">All use rbc-preferences API for credentials and preferences</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>Transfer Funds / Securities</span>
|
||||||
|
<span class="api-badge">rbc-preferences</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">All use rbc-preferences API for credentials and preferences</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>Screeners</span>
|
||||||
|
<span class="api-badge">Multiple APIs</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">rbc-analyst-picklists</div>
|
||||||
|
<div class="url-item">rbc-curated-research</div>
|
||||||
|
<div class="url-item">rbc-preferences</div>
|
||||||
|
<div class="url-item">rbc-quote</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>Investor's Toolkit</span>
|
||||||
|
<span class="api-badge">Multiple APIs</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">rbc-analyst-picklists</div>
|
||||||
|
<div class="url-item">rbc-curated-research</div>
|
||||||
|
<div class="url-item">rbc-fundamentals</div>
|
||||||
|
<div class="url-item">rbc-preferences</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>Markets Section Pages</span>
|
||||||
|
<span class="api-badge">rbc-preferences</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">Sectors & Industries - rbc-preferences</div>
|
||||||
|
<div class="url-item">Calendar - rbc-preferences</div>
|
||||||
|
<div class="url-item">News & Headlines - rbc-preferences</div>
|
||||||
|
<div class="url-item">Market Commentary - rbc-preferences</div>
|
||||||
|
<div class="url-item">Technical Analysis - rbc-preferences</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="api-section">
|
||||||
|
<div class="api-header" onclick="toggleSection(this)">
|
||||||
|
<div class="api-name">
|
||||||
|
<span>GICs, Bonds and Fixed Income</span>
|
||||||
|
<span class="api-badge">rbc-preferences</span>
|
||||||
|
</div>
|
||||||
|
<button class="toggle-btn" onclick="event.stopPropagation(); toggleSection(this.parentElement)">Toggle</button>
|
||||||
|
</div>
|
||||||
|
<div class="api-urls">
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials</div>
|
||||||
|
<div class="url-item">https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function toggleSection(element) {
|
||||||
|
const header = element.classList.contains('api-header') ? element : element.parentElement;
|
||||||
|
const urls = header.nextElementSibling;
|
||||||
|
|
||||||
|
header.classList.toggle('active');
|
||||||
|
urls.classList.toggle('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
function expandAll() {
|
||||||
|
const allSections = document.querySelectorAll('.api-urls');
|
||||||
|
const allHeaders = document.querySelectorAll('.api-header');
|
||||||
|
|
||||||
|
allSections.forEach(section => section.classList.add('show'));
|
||||||
|
allHeaders.forEach(header => header.classList.add('active'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function collapseAll() {
|
||||||
|
const allSections = document.querySelectorAll('.api-urls');
|
||||||
|
const allHeaders = document.querySelectorAll('.api-header');
|
||||||
|
|
||||||
|
allSections.forEach(section => section.classList.remove('show'));
|
||||||
|
allHeaders.forEach(header => header.classList.remove('active'));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- start of with goals should be and then meet and refine them
|
||||||
|
- TeamFlect -> Reviews -> Complete these and then talk with Lance
|
||||||
|
|
||||||
|
- Present decoupled design two weeks form now
|
||||||
|
- Prep release -> talk with Jeremy and Hao on Friday and Monday
|
||||||
32
src/scratchpad/random notes/-Mar 7–9, 2025.txt
Normal file
32
src/scratchpad/random notes/-Mar 7–9, 2025.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
-Mar 7–9, 2025
|
||||||
|
|
||||||
|
Vancouver Convention Centre
|
||||||
|
|
||||||
|
1055 Canada Pl
|
||||||
|
Vancouver, BC V6C 0C3, Canada
|
||||||
|
|
||||||
|
-Apr 11–13, 2025
|
||||||
|
|
||||||
|
Georgia World Congress Center
|
||||||
|
|
||||||
|
285 Andrew Young International Blvd NW
|
||||||
|
Atlanta, GA 30313, USA
|
||||||
|
|
||||||
|
-May 2–4, 2025
|
||||||
|
|
||||||
|
Baird Center
|
||||||
|
|
||||||
|
400 W Wisconsin Ave
|
||||||
|
Milwaukee, WI 53203, USA
|
||||||
|
|
||||||
|
-North America International Championships
|
||||||
|
|
||||||
|
-June 13–15, 2025
|
||||||
|
|
||||||
|
Ernest N. Morial Convention Center
|
||||||
|
|
||||||
|
900 Convention Center Blvd
|
||||||
|
New Orleans, LA 70130
|
||||||
|
USA
|
||||||
|
|
||||||
|
Worlds 2025: August 15-17 in Anaheim, California
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
'Log files:
|
||||||
|
C:\Users\GregJacobs\AppData\Local\npm-cache\_logs\2025-03-26T19_19_21_647Z-debug-0.log
|
||||||
|
|
||||||
|
# npm resolution error report
|
||||||
|
|
||||||
|
While resolving: DirectInvesting@1.0.0
|
||||||
|
Found: eslint@3.19.0
|
||||||
|
node_modules/eslint
|
||||||
|
dev eslint@"^3.19.0" from the root project
|
||||||
|
|
||||||
|
Could not resolve dependency:
|
||||||
|
peer eslint@">=7" from @markit/eslint-config-markit@1.2.0
|
||||||
|
node_modules/@markit/eslint-config-markit
|
||||||
|
dev @markit/eslint-config-markit@"^1.0.1" from the root project
|
||||||
|
|
||||||
|
Fix the upstream dependency conflict, or retry
|
||||||
|
this command with --force or --legacy-peer-deps
|
||||||
|
to accept an incorrect (and potentially broken) dependency resolution.
|
||||||
634
src/scratchpad/random notes/BEST FF SO FAR.txt
Normal file
634
src/scratchpad/random notes/BEST FF SO FAR.txt
Normal file
@@ -0,0 +1,634 @@
|
|||||||
|
BEST FF SO FAR
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function creates a modal dialog that allows the user to toggle feature flags.
|
||||||
|
* It retrieves the feature flags from the session storage, creates checkboxes for each flag,
|
||||||
|
* and saves the updated flags back to the session storage when the user clicks the save button.
|
||||||
|
* The modal dialog is appended to the document body and can be closed by clicking the save button.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*/
|
||||||
|
let data = sessionStorage.getItem('rbc_di_session');
|
||||||
|
let parsedData = JSON.parse(data);
|
||||||
|
let features = parsedData.features || {};
|
||||||
|
|
||||||
|
let modal = document.createElement('div');
|
||||||
|
modal.className = 'rbc-feature-flags-modal';
|
||||||
|
modal.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 9999;
|
||||||
|
width: 90%;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Add modal header
|
||||||
|
let modalHeader = document.createElement('div');
|
||||||
|
modalHeader.style.cssText = `
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
padding: 24px 24px 0 24px;
|
||||||
|
border-bottom: 1px solid #e6e6e6;
|
||||||
|
background-color: #ffffff;
|
||||||
|
z-index: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let headerTitle = document.createElement('h1');
|
||||||
|
headerTitle.innerText = 'Feature Flags Manager';
|
||||||
|
headerTitle.style.cssText = `
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.3;
|
||||||
|
`;
|
||||||
|
|
||||||
|
modalHeader.appendChild(headerTitle);
|
||||||
|
modal.appendChild(modalHeader);
|
||||||
|
|
||||||
|
// Container for new features (moved to top)
|
||||||
|
let newFeaturesSection = document.createElement('div');
|
||||||
|
newFeaturesSection.style.cssText = `
|
||||||
|
padding: 0 24px 24px 24px;
|
||||||
|
border-bottom: 1px solid #e6e6e6;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let newFeatureTitle = document.createElement('h3');
|
||||||
|
newFeatureTitle.innerText = 'Add New Feature Flags';
|
||||||
|
newFeatureTitle.style.cssText = `
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
`;
|
||||||
|
newFeaturesSection.appendChild(newFeatureTitle);
|
||||||
|
|
||||||
|
// Two-column container for inputs and suggestions
|
||||||
|
let twoColumnContainer = document.createElement('div');
|
||||||
|
twoColumnContainer.style.cssText = `
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 24px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Left column - Container for all new feature inputs
|
||||||
|
let leftColumn = document.createElement('div');
|
||||||
|
let newFeaturesContainer = document.createElement('div');
|
||||||
|
newFeaturesContainer.id = 'newFeaturesContainer';
|
||||||
|
leftColumn.appendChild(newFeaturesContainer);
|
||||||
|
|
||||||
|
// Function to create a new feature input row
|
||||||
|
function createNewFeatureRow() {
|
||||||
|
let newFeatureContainer = document.createElement('div');
|
||||||
|
newFeatureContainer.className = 'new-feature-row';
|
||||||
|
newFeatureContainer.style.cssText = `
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let newFeatureCheckbox = document.createElement('input');
|
||||||
|
newFeatureCheckbox.type = 'checkbox';
|
||||||
|
newFeatureCheckbox.checked = true;
|
||||||
|
newFeatureCheckbox.className = 'new-feature-checkbox';
|
||||||
|
newFeatureCheckbox.style.cssText = `
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
accent-color: #006ac3;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let newFeatureInput = document.createElement('input');
|
||||||
|
newFeatureInput.type = 'text';
|
||||||
|
newFeatureInput.placeholder = 'Enter feature flag name...';
|
||||||
|
newFeatureInput.className = 'new-feature-input';
|
||||||
|
newFeatureInput.style.cssText = `
|
||||||
|
flex: 1;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
newFeatureInput.addEventListener('focus', function() {
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
this.style.outline = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
newFeatureInput.addEventListener('blur', function() {
|
||||||
|
this.style.borderColor = '#d1d5db';
|
||||||
|
});
|
||||||
|
newFeatureInput.addEventListener('keydown', handleNewFeatureInputKeydown); // Attach keydown listener
|
||||||
|
|
||||||
|
let removeButton = document.createElement('button');
|
||||||
|
removeButton.innerText = 'Remove';
|
||||||
|
removeButton.style.cssText = `
|
||||||
|
padding: 6px 12px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #666666;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
removeButton.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#ffebee';
|
||||||
|
this.style.borderColor = '#d32f2f';
|
||||||
|
this.style.color = '#d32f2f';
|
||||||
|
});
|
||||||
|
|
||||||
|
removeButton.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.borderColor = '#d1d5db';
|
||||||
|
this.style.color = '#666666';
|
||||||
|
});
|
||||||
|
|
||||||
|
removeButton.addEventListener('click', function() {
|
||||||
|
newFeatureContainer.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
newFeatureContainer.appendChild(newFeatureCheckbox);
|
||||||
|
newFeatureContainer.appendChild(newFeatureInput);
|
||||||
|
newFeatureContainer.appendChild(removeButton);
|
||||||
|
|
||||||
|
return newFeatureContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add initial new feature row
|
||||||
|
newFeaturesContainer.appendChild(createNewFeatureRow());
|
||||||
|
|
||||||
|
// Add button to add more feature rows
|
||||||
|
let addFeatureButton = document.createElement('button');
|
||||||
|
addFeatureButton.innerText = '+ Add Another Feature Flag';
|
||||||
|
addFeatureButton.style.cssText = `
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #006ac3;
|
||||||
|
border: 1px solid #006ac3;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 8px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
addFeatureButton.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
});
|
||||||
|
|
||||||
|
addFeatureButton.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
});
|
||||||
|
|
||||||
|
addFeatureButton.addEventListener('click', function() {
|
||||||
|
newFeaturesContainer.appendChild(createNewFeatureRow());
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
});
|
||||||
|
|
||||||
|
leftColumn.appendChild(addFeatureButton);
|
||||||
|
|
||||||
|
// Right column - Create suggestions column
|
||||||
|
let suggestionsColumn = document.createElement('div');
|
||||||
|
suggestionsColumn.style.cssText = `
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 200px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let suggestionsTitle = document.createElement('h3');
|
||||||
|
suggestionsTitle.innerText = 'Suggestions';
|
||||||
|
suggestionsTitle.style.cssText = `
|
||||||
|
margin: 0 0 12px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
`;
|
||||||
|
suggestionsColumn.appendChild(suggestionsTitle);
|
||||||
|
|
||||||
|
let suggestionsList = document.createElement('div');
|
||||||
|
suggestionsList.id = 'suggestionsList';
|
||||||
|
suggestionsColumn.appendChild(suggestionsList);
|
||||||
|
|
||||||
|
// Add columns to two-column container
|
||||||
|
twoColumnContainer.appendChild(leftColumn);
|
||||||
|
twoColumnContainer.appendChild(suggestionsColumn);
|
||||||
|
|
||||||
|
// Add two-column container to the section
|
||||||
|
newFeaturesSection.appendChild(twoColumnContainer);
|
||||||
|
modal.appendChild(newFeaturesSection);
|
||||||
|
|
||||||
|
// Load suggestions from local storage
|
||||||
|
let savedFlags = JSON.parse(localStorage.getItem('savedFeatureFlags') || '[]');
|
||||||
|
|
||||||
|
// Initialize suggestions section with predefined feature flags
|
||||||
|
let initialSuggestions = [
|
||||||
|
'marketsResearchWebComponent',
|
||||||
|
'rcSectorAndEvents',
|
||||||
|
'rcMarkemovers',
|
||||||
|
'rcBreakingNews',
|
||||||
|
'rcReportsAndCommentary',
|
||||||
|
'optionsStrikePriceExperience',
|
||||||
|
'useRbcXrefForUs',
|
||||||
|
'sentryLogging'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Merge initial suggestions with saved flags
|
||||||
|
savedFlags = [...new Set([...savedFlags, ...initialSuggestions])];
|
||||||
|
localStorage.setItem('savedFeatureFlags', JSON.stringify(savedFlags));
|
||||||
|
|
||||||
|
// Populate suggestions list
|
||||||
|
savedFlags.forEach(flag => {
|
||||||
|
let suggestionItem = document.createElement('button');
|
||||||
|
suggestionItem.innerText = flag;
|
||||||
|
suggestionItem.style.cssText = `
|
||||||
|
padding: 6px 12px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
margin-right: 6px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #006ac3;
|
||||||
|
border: 1px solid #006ac3;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
`;
|
||||||
|
|
||||||
|
suggestionItem.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
});
|
||||||
|
|
||||||
|
suggestionItem.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
});
|
||||||
|
|
||||||
|
suggestionItem.addEventListener('click', function() {
|
||||||
|
let newRow = createNewFeatureRow();
|
||||||
|
newRow.querySelector('.new-feature-input').value = flag;
|
||||||
|
newFeaturesContainer.appendChild(newRow);
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
});
|
||||||
|
|
||||||
|
suggestionsList.appendChild(suggestionItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save new feature flags to local storage
|
||||||
|
function saveFeatureFlagToLocalStorage(flag) {
|
||||||
|
if (!savedFlags.includes(flag)) {
|
||||||
|
savedFlags.push(flag);
|
||||||
|
localStorage.setItem('savedFeatureFlags', JSON.stringify(savedFlags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define saveButton earlier in the code
|
||||||
|
let saveButton = document.createElement('button');
|
||||||
|
saveButton.innerText = 'Save Changes';
|
||||||
|
saveButton.style.cssText = `
|
||||||
|
padding: 12px 24px;
|
||||||
|
background-color: #006ac3;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 2px solid #006ac3;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
saveButton.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#0051a5';
|
||||||
|
this.style.borderColor = '#0051a5';
|
||||||
|
});
|
||||||
|
|
||||||
|
saveButton.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = '#006ac3';
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update save button to store new flags in local storage
|
||||||
|
saveButton.addEventListener('click', function() {
|
||||||
|
const newFeatureRows = modal.querySelectorAll('.new-feature-row');
|
||||||
|
newFeatureRows.forEach(function(row) {
|
||||||
|
const input = row.querySelector('.new-feature-input');
|
||||||
|
if (input.value && input.value.trim() !== '') {
|
||||||
|
saveFeatureFlagToLocalStorage(input.value.trim());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Action buttons container
|
||||||
|
let actionButtons = document.createElement('div');
|
||||||
|
actionButtons.style.cssText = `
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 24px;
|
||||||
|
border-top: 1px solid #e6e6e6;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-radius: 0 0 8px 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Append actionButtons to the modal later in the code
|
||||||
|
modal.appendChild(actionButtons);
|
||||||
|
|
||||||
|
// Append saveButton to actionButtons after its definition
|
||||||
|
actionButtons.appendChild(saveButton);
|
||||||
|
|
||||||
|
// Existing Features Section
|
||||||
|
let existingFeaturesHeader = document.createElement('h3');
|
||||||
|
existingFeaturesHeader.innerText = 'Existing Feature Flags';
|
||||||
|
existingFeaturesHeader.style.cssText = `
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
padding: 0 24px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
`;
|
||||||
|
modal.appendChild(existingFeaturesHeader);
|
||||||
|
|
||||||
|
// Main content container for existing features
|
||||||
|
let modalContent = document.createElement('div');
|
||||||
|
modalContent.style.cssText = `
|
||||||
|
padding: 0 24px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: calc(100vh - (modalHeader.offsetHeight + actionButtons.offsetHeight));
|
||||||
|
`;
|
||||||
|
|
||||||
|
for (let key in features) {
|
||||||
|
if (features.hasOwnProperty(key) && typeof features[key] === 'boolean') {
|
||||||
|
let checkboxContainer = document.createElement('div');
|
||||||
|
checkboxContainer.style.cssText = `
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
checkboxContainer.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
});
|
||||||
|
|
||||||
|
checkboxContainer.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = '#fafafa';
|
||||||
|
this.style.borderColor = '#e6e6e6';
|
||||||
|
});
|
||||||
|
|
||||||
|
let checkbox = document.createElement('input');
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.id = key;
|
||||||
|
checkbox.checked = features[key];
|
||||||
|
checkbox.style.cssText = `
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
accent-color: #006ac3;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let label = document.createElement('label');
|
||||||
|
label.htmlFor = key;
|
||||||
|
label.innerText = key;
|
||||||
|
label.style.cssText = `
|
||||||
|
flex: 1;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #333333;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let deleteButton = document.createElement('button');
|
||||||
|
deleteButton.innerHTML = '×';
|
||||||
|
deleteButton.style.cssText = `
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 18px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
deleteButton.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#ffebee';
|
||||||
|
this.style.color = '#d32f2f';
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteButton.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.color = '#666666';
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteButton.addEventListener('click', function() {
|
||||||
|
delete features[key];
|
||||||
|
checkboxContainer.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
checkboxContainer.appendChild(checkbox);
|
||||||
|
checkboxContainer.appendChild(label);
|
||||||
|
checkboxContainer.appendChild(deleteButton);
|
||||||
|
modalContent.appendChild(checkboxContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modal.appendChild(modalContent);
|
||||||
|
|
||||||
|
// Close button
|
||||||
|
let closeButton = document.createElement('button');
|
||||||
|
closeButton.innerHTML = '×';
|
||||||
|
closeButton.style.cssText = `
|
||||||
|
position: absolute;
|
||||||
|
top: 16px;
|
||||||
|
right: 16px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #666666;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
closeButton.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#f5f5f5';
|
||||||
|
this.style.color = '#333333';
|
||||||
|
});
|
||||||
|
|
||||||
|
closeButton.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.color = '#666666';
|
||||||
|
});
|
||||||
|
|
||||||
|
closeButton.addEventListener('click', function() {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
document.body.removeChild(overlay);
|
||||||
|
});
|
||||||
|
|
||||||
|
let cancelButton = document.createElement('button');
|
||||||
|
cancelButton.innerText = 'Cancel';
|
||||||
|
cancelButton.style.cssText = `
|
||||||
|
padding: 12px 24px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #006ac3;
|
||||||
|
border: 2px solid #006ac3;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
cancelButton.addEventListener('mouseenter', function() {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
this.style.borderColor = '#0051a5';
|
||||||
|
this.style.color = '#0051a5';
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.addEventListener('mouseleave', function() {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
this.style.color = '#006ac3';
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.addEventListener('click', function() {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
document.body.removeChild(overlay);
|
||||||
|
});
|
||||||
|
|
||||||
|
actionButtons.appendChild(cancelButton);
|
||||||
|
actionButtons.appendChild(saveButton);
|
||||||
|
|
||||||
|
modal.appendChild(closeButton);
|
||||||
|
modal.appendChild(actionButtons);
|
||||||
|
|
||||||
|
let overlay = document.createElement('div');
|
||||||
|
overlay.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 9998;
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
|
// Close modal on Escape key
|
||||||
|
function closeFeatureFlagsModal() {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
document.body.removeChild(overlay);
|
||||||
|
document.removeEventListener('keydown', escListener);
|
||||||
|
}
|
||||||
|
function escListener(e) {
|
||||||
|
if (e.key === 'Escape') closeFeatureFlagsModal();
|
||||||
|
}
|
||||||
|
document.addEventListener('keydown', escListener);
|
||||||
|
|
||||||
|
// Update Enter key behavior to create only one new feature flag input
|
||||||
|
function handleNewFeatureInputKeydown(e) {
|
||||||
|
if (e.key === 'Enter' && !e.ctrlKey) {
|
||||||
|
// Add a single new feature flag row
|
||||||
|
e.preventDefault();
|
||||||
|
if (!newFeaturesContainer.querySelector('.new-feature-row:last-child .new-feature-input').value.trim()) {
|
||||||
|
return; // Prevent adding a new row if the last input is empty
|
||||||
|
}
|
||||||
|
newFeaturesContainer.appendChild(createNewFeatureRow());
|
||||||
|
} else if (e.key === 'Enter' && e.ctrlKey) {
|
||||||
|
// Trigger the Save Changes button
|
||||||
|
e.preventDefault();
|
||||||
|
saveButton.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the keydown listener to all new feature inputs
|
||||||
|
function attachKeydownListenerToNewFeatureInputs() {
|
||||||
|
const newFeatureInputs = modal.querySelectorAll('.new-feature-input');
|
||||||
|
newFeatureInputs.forEach(input => {
|
||||||
|
input.removeEventListener('keydown', handleNewFeatureInputKeydown); // Remove existing listener to avoid duplicates
|
||||||
|
input.addEventListener('keydown', handleNewFeatureInputKeydown);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure listeners are attached after adding new rows
|
||||||
|
addFeatureButton.addEventListener('click', function() {
|
||||||
|
newFeaturesContainer.appendChild(createNewFeatureRow());
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Attach listeners to initial rows
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
|
||||||
|
// Add event listener for Enter and Ctrl+Enter in the Add New Feature Flag input
|
||||||
|
newFeaturesContainer.addEventListener('keydown', function(e) {
|
||||||
|
if (e.target.classList.contains('new-feature-input')) {
|
||||||
|
if (e.key === 'Enter' && !e.ctrlKey) {
|
||||||
|
// Simulate Add Another Feature Flag button click
|
||||||
|
newFeaturesContainer.appendChild(createNewFeatureRow());
|
||||||
|
e.preventDefault();
|
||||||
|
} else if (e.key === 'Enter' && e.ctrlKey) {
|
||||||
|
// Simulate Save Changes button click
|
||||||
|
saveButton.click();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add a style block to isolate bookmarklet styles from the main website
|
||||||
|
let styleBlock = document.createElement('style');
|
||||||
|
styleBlock.innerHTML = `
|
||||||
|
.rbc-feature-flags-modal input[type="checkbox"] + label::before {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: -25%;
|
||||||
|
background-color: transparent;
|
||||||
|
height: 26px;
|
||||||
|
width: 26px;
|
||||||
|
margin: 1px;
|
||||||
|
margin-bottom:-1px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Append the style block to the modal
|
||||||
|
modal.appendChild(styleBlock);
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Book Regression Briefing Meeting -Thurs or Fri (Monday at latest)
|
||||||
|
- Have Test Plan Prepped
|
||||||
|
- Go over what we will test and confluence
|
||||||
|
-
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
D4nc3ing0m13TTE$
|
||||||
48
src/scratchpad/random notes/GitHub copilot and POC.txt
Normal file
48
src/scratchpad/random notes/GitHub copilot and POC.txt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
GitHub copilot and POC
|
||||||
|
|
||||||
|
Developer for RBC
|
||||||
|
Been working on research consolidation
|
||||||
|
Significant changes
|
||||||
|
From individual contrib that worked under the dev guidelines to a more senior role allowing me to solve more of these problems without assistance
|
||||||
|
Good to highlight the GH Copilot and
|
||||||
|
|
||||||
|
Q2
|
||||||
|
Poc able to reengineer a process
|
||||||
|
unify a team around the approach and process
|
||||||
|
Owning the revamp of this
|
||||||
|
Significant decrease in time moids were open as well as a drop in moids being sent to us
|
||||||
|
|
||||||
|
copilot being one of the first to volunteer to head this to figure out how it works for us and tips and tricks given to others from
|
||||||
|
ability to go out find innovative ways to do the job and bring back to team
|
||||||
|
|
||||||
|
Aspects do i enjoy is good for lances answer
|
||||||
|
|
||||||
|
major challenges
|
||||||
|
- universal challenge
|
||||||
|
- Been through a lot of change with the team. Laid off, structure changes
|
||||||
|
- Seen as a major challenge
|
||||||
|
- Been able to overcome it very well
|
||||||
|
|
||||||
|
Biggest Accomplishment
|
||||||
|
- sets Lance up to expand on this
|
||||||
|
|
||||||
|
Goal Oriented Questions
|
||||||
|
|
||||||
|
Last Assessment
|
||||||
|
- make the smaller goals part of a larger vision
|
||||||
|
|
||||||
|
What goals were not accomplished and why
|
||||||
|
- Answer is fine
|
||||||
|
|
||||||
|
Goals for coming year
|
||||||
|
- Senior developer
|
||||||
|
- Keep increasing knowledge change this to actual ways i will increase knowledge and
|
||||||
|
- Higher senior level must wider understanding of the systems in play along with the tools
|
||||||
|
how things operate from front end all the way to where we get data from
|
||||||
|
- How we acquire the data for the backend
|
||||||
|
- Being able to break down projects sequentially so we can better move through them efficiently
|
||||||
|
-
|
||||||
|
|
||||||
|
Grow and expand people interaction inside and outside team
|
||||||
|
this past year Shored up a lot of the technical knowledge that was needed to bolster
|
||||||
|
This coming year more opportunities to take leadership roles
|
||||||
30
src/scratchpad/random notes/Market Apps.txt
Normal file
30
src/scratchpad/random notes/Market Apps.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
Market Apps
|
||||||
|
- We positioned ourselves to be first to dev custom for this
|
||||||
|
- Jeremy part of web component working group
|
||||||
|
- I get to work on backend and frontend
|
||||||
|
- Building repo where there are a lot of other talented developers working in it
|
||||||
|
- Start utilizing a lot of the smaller components
|
||||||
|
- Figure out kebab menu custom slots etc
|
||||||
|
-
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
|
||||||
|
Triton -
|
||||||
|
pinkfed api we can hit
|
||||||
|
|
||||||
|
Couple takes
|
||||||
|
reading the spec on oauth
|
||||||
|
- just delete token from the browser is the official method suggested
|
||||||
|
we currently support revoke endpoint/api
|
||||||
|
- shuts down the token
|
||||||
|
- not instant (fast but not page load fast and is inconsistent with time it takes (up to 2 minutes was mentioned as a possibility))
|
||||||
|
|
||||||
|
tokens aren't sessions
|
||||||
|
giving x amount of time essentially and shuts down after two hours
|
||||||
|
|
||||||
|
By the standard just delete it if we can have the client do that
|
||||||
|
|
||||||
|
Doc on revoke API endpoint:
|
||||||
|
https://communify.atlassian.net/wiki/spaces/MOD/pages/22316726/How+to+Revoke+a+token
|
||||||
33
src/scratchpad/random notes/Monitoring.txt
Normal file
33
src/scratchpad/random notes/Monitoring.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
Monitoring
|
||||||
|
TKT-379 - MOID-496130 - Can be closed bc it has PJira (DIP-12819) - MOID Board locked
|
||||||
|
TKT-367 - MOID-496780 - Wanted us to add authors and can be closed but no confirm from RBC but we can see it in PROD. Shouldnt be a MOID and pushback next time
|
||||||
|
TKT-373 - MOID-496419 - DataPower cert renewal. More work to install Feb 25th NTT can install on that date
|
||||||
|
TKT-390 - MOID-495171 - Srini working this ticket should be CAD but in USD currency
|
||||||
|
TKT-382 - MOID-496059 - Advanced Charts not showing add events or to select them - One day then the next it was fine
|
||||||
|
MOID-496653 - DOTCOM error maybe quote server release
|
||||||
|
|
||||||
|
OPEN
|
||||||
|
MOID-498208 - Another instance of above error
|
||||||
|
MOID-497718 - AMD is a CDR its loading data is not right. Maybe no CDR is loading? Reach out to Prometheus about this? no multexrepno outsde of NSQ
|
||||||
|
TKT-255 - MOID-497478 - Close this change request and link to PJira - DIP-12823
|
||||||
|
TKT-262 - MOID-496971 - Symbols supposed to be removed. seems like its a feed they own
|
||||||
|
MOID-488294 - Sev 6, WM issues where symbol BAM isn't returning fundamental ratings (coming from two diff feeds)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MStar credit rating
|
||||||
|
Quantitative Valuation
|
||||||
|
api will return true other will be false
|
||||||
|
|
||||||
|
Valuation triggers the event
|
||||||
|
Have to filter out since we dont have that data
|
||||||
|
Morningstars Take - Look into api and how its used
|
||||||
|
|
||||||
|
|
||||||
|
All Tickets Except Closed - project = TKT AND status != Closed AND "global client[short text]" ~ "RBC" ORDER BY created DESC
|
||||||
|
All Open or Triaged Tickets - project = TKT AND status IN (Open, Triage) AND "global client[short text]" ~ "RBC" ORDER BY created DESC
|
||||||
|
All Closed Tickets - project = TKT AND status = Closed AND "global client[short text]" ~ "RBC" ORDER BY created DESC
|
||||||
|
All Monitoring Tickets - project = TKT AND status = Monitoring AND "global client[short text]" ~ "RBC" ORDER BY created DESC
|
||||||
|
All Waiting For Client Tickets - project = TKT AND status = "Waiting for customer" AND "global client[short text]" ~ "RBC" ORDER BY created DESC
|
||||||
|
|
||||||
|
project = TKT AND status = "Escalated to Internal Team" AND "Team[Team]" IN (Rigel, ea6f5b1a-be11-48cb-b014-e6083f5d305f) AND "global client[short text]" ~ "RBC" ORDER BY created DESC
|
||||||
15
src/scratchpad/random notes/Name.txt
Normal file
15
src/scratchpad/random notes/Name.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Name
|
||||||
|
gEjI4Fvm
|
||||||
|
|
||||||
|
passcode
|
||||||
|
cT-2zoALCxVYU9XuxwK29VmBNf-nGjKwgKuG_DvfnJj-
|
||||||
|
|
||||||
|
maven settings.xml
|
||||||
|
<server>
|
||||||
|
<id>${server}</id>
|
||||||
|
<username>gEjI4Fvm</username>
|
||||||
|
<password>cT-2zoALCxVYU9XuxwK29VmBNf-nGjKwgKuG_DvfnJj-</password>
|
||||||
|
</server>
|
||||||
|
|
||||||
|
base64 user:pwd
|
||||||
|
Z0VqSTRGdm06Y1QtMnpvQUxDeFZZVTlYdXh3SzI5Vm1CTmYtbkdqS3dnS3VHX0R2Zm5Kai0=
|
||||||
1
src/scratchpad/random notes/Rbc-api - .net.txt
Normal file
1
src/scratchpad/random notes/Rbc-api - .net.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Rbc-api - .net
|
||||||
2
src/scratchpad/random notes/Regression Meeting.txt
Normal file
2
src/scratchpad/random notes/Regression Meeting.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Regression Meeting
|
||||||
|
-
|
||||||
58
src/scratchpad/random notes/TKTs Closed.txt
Normal file
58
src/scratchpad/random notes/TKTs Closed.txt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
TKTs Closed
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-2165 - Closed in favor of https://communify.atlassian.net/browse/DIP-13115 and set effective close date to May 5th 2025
|
||||||
|
- Should investigate the 40x errors and if seem legit close and comment on it. Tiered can do this. Crucial to close as it prevents other tickets for DI DQ from spawning so we wouldn't know about outage
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5278 - Closed and a RCA is underway in ticket https://communify.atlassian.net/browse/RCA-1301 - set effective close date as June 19th 2025
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-6112 - Sent back to T2 as they can handle the renewal - Sent back and handled the renewal...
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5884 - Sent back to T2 as they can handle the renewal - Sent back and handled the renewal...
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5215 - Could have been closed over a week ago based on comment from RBC saying its fine now. David reopened and assigned to me saying this 'Real Resolution Date' might not be for SLA so need to check with CIM
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-4423 - Created PJIRA Ticket https://communify.atlassian.net/browse/DIP-13130 to handle
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-6148 - Created PJIRA Ticket https://communify.atlassian.net/browse/DIP-13131 to handle
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-6146 - Created PJIRA Ticket https://communify.atlassian.net/browse/DIP-13130 to handle
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5466 - Created PJIRA Ticket https://communify.atlassian.net/browse/DIP-13132 to handle
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TKT Updated
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5543 - Screenshots need to be more contextual and less zoomed in. Found QIDs and asked Srini to look into it
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-3417 - Need updated from Michael, Lance or Sean on this
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5082 - Srini to pick up Wed and create PJIRA ticket in favor of this ticket so we can close
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5549 - Ask srini about the QID Ambika mentioned and if we need to still have this ticket as its passing now
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5836 - Checked SSL Shopper and see that our services cert is valid and the DP URL cannot be found. Asked to check in with Vishnu periasami at RBC who does their certs
|
||||||
|
|
||||||
|
- https://communify.atlassian.net/browse/TKT-5366 - Closing because I cannot understand the ask and need better documentation. Also lack of knowledge documented around WMApi and how to check apis in swagger - https://www.rbcinsight.com/WMApi/docs#/CompanyAPI/get_WMApi_company__wsodCompany_ - Last to have knowledge of this was Hiral
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
|
||||||
|
PJira Tickets In Favor of TKT needing fields updated
|
||||||
|
- https://communify.atlassian.net/browse/DIP-13115
|
||||||
|
- https://communify.atlassian.net/browse/DIP-13134
|
||||||
|
- https://communify.atlassian.net/browse/DIP-13132
|
||||||
|
- https://communify.atlassian.net/browse/DIP-13130
|
||||||
|
- https://communify.atlassian.net/browse/DIP-13131
|
||||||
|
|
||||||
|
|
||||||
|
Things to do:
|
||||||
|
- Srini to help with WMAPI
|
||||||
|
- Create a PJira for TKT-6148 for increase CPU to 300 for both CTC and PTC to accommodate high usage averages - https://communify.atlassian.net/browse/DIP-13131
|
||||||
|
- Create a PJira for TKT-6146 to increase container size from default 3 to 5 and reduce memory from 200 to 120 - https://communify.atlassian.net/browse/DIP-13130
|
||||||
|
- Create a PJIRA for TKT-5466 to increase CPU to 250 for both CTC and PTC to accommodate high usage averages - https://communify.atlassian.net/browse/DIP-13132
|
||||||
|
- Create a PJIRA for TKT-5782 - To increase the number of containers to 5 from 3 to accomidate high usage averages - https://communify.atlassian.net/browse/DIP-13134
|
||||||
|
- Create a PJIRA ticket for TKT-5725
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
add a transformer to anything that ends in svg?component
|
||||||
13
src/scratchpad/random notes/clear site data.txt
Normal file
13
src/scratchpad/random notes/clear site data.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
clear site data
|
||||||
|
the cache or storage
|
||||||
|
Response.write header
|
||||||
|
|
||||||
|
https://wwwx3.steroyalbank.com/investing/markets/alerts.asp
|
||||||
|
|
||||||
|
https://wwwx3.steroyalbank.com/DirectInvesting/Research/Session/Clear?clearSiteData=true
|
||||||
|
|
||||||
|
https://wwwx3.steroyalbank.com/DirectInvesting/Research/Session/Clear
|
||||||
|
https://www.rbcinsight.com/wm/?user_id=testcsadmin&user_password=password&user_tier=WSOD_CS_Admin
|
||||||
|
|
||||||
|
https://www.rbcinsight.com/wm/?user_id=testwmconnectadmin&user_password=password&user_tier=WMConnect_Admin
|
||||||
|
|
||||||
4
src/scratchpad/random notes/components to component.txt
Normal file
4
src/scratchpad/random notes/components to component.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
components to component
|
||||||
|
remove rbc fonts and styling css
|
||||||
|
rmove htmlTagId
|
||||||
|
make sure component
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
curl 'https://www1.steroyalbank.com/cgi-bin/rbaccess/rbunxcgi?F22=4WN600S&7ASERVER=N601LD&LANGUAGE=ENGLISH&7ASCRIPT=/WebUI/OrderEntry/RefreshOptionQuote&symbol=PLTR&market=US&expiry=062025&strike=10&callOrPut=C&_=1740580990206' \
|
||||||
|
-H 'accept: text/html, */*; q=0.01' \
|
||||||
|
-H 'accept-language: en-US,en;q=0.9' \
|
||||||
|
-b $'Tn497djuWn=A91b9rCTAQAAsTxCIpuW7pwpWa1DFi3BLjXLBGrT_9wiTNkA4QSqSqBojK1hAWAvs4IXTu_LwH8AAEB3AAAAAA|1|0|6a4475f10cada34c311bc37e0a3dcee7671df3a3; _gcl_au=1.1.561709616.1733840757; _ga=GA1.1.656996841.1733840757; OptanonAlertBoxClosed=2024-12-10T16:01:14.860Z; 3mReca=0xdeadbeef; TS01a5d410=010dfc82295f5b88a35a857bf01865140e7431cb2e2a4d6a8c1fa1be9c4543c8a1ff37b3d2955036833215c3bf123d18e3bec65c42; TS0149ca65=010dfc8229db7909234cc9cbc180c7eb35550a552c71cf6e6c3b5a53c2415802d7066c50aaab890c802e5f71cb222fdd1a3619136a; RBCHomePage=homepage=1; MindeventBanner=; TS01aecb63=010dfc8229db7909234cc9cbc180c7eb35550a552c71cf6e6c3b5a53c2415802d7066c50aaab890c802e5f71cb222fdd1a3619136a; rxVisitor=1740167271225BFECSQOOHSENOMF7BFAS3NOMJJ301T9K; IV_JCT=%2Fmga; __RequestVerificationToken_L1dlYlVJ0=mtbFowLUHNBznjI0Sv_sQg7nEKi2FIPt1INJzs1FZigsVm3ZyWZdesxk3lY01o4E66j3G3KTeYaxVK41H71wm1f7YHe4tdTxqYzqynOJkOQ1; DI-SESSION-KEY=SCGMHNDGTYIHNPJWDZMZDNMTFLZPOWTC; dtCookie=v_4_srv_15_sn_9CA21A332E3B9455E4FED93F0F9BF935_app-3A817565fe18e0696d_1_app-3A94c41e43fb93f07b_1_ol_0_perc_100000_mul_1_rcs-3Acss_0; TS01000928=010dfc8229578f2cff9750f0261d09362b3b1d151c3c39b27885bd6d2033864617bee1899d367ba04f189ee6f489626ce274890bb2; TS013a5881=010dfc8229b60fabe1da08e6c8bed9a794c0bb906f70ce8f6bbc476832b817938d4ca56ff7377ad12b83553b233805fc5d76a5599e; 3MLSEC=TQGzZyBQFSi.ZxAwAAAUMQAAeH4CAA__; 3M_DEST=QUHstTJBnFl7sk5ALczcvjfs-AUsb8UXuQrrQjc6ull-P.qEeS7.KYeVJmg9ytBfJedTbyHCOONI8iA0cn1WOrCJ0kTTjaxmGCU?; RBCDict=SGID=68f5337f833176340076346a370035003201&language=ENGLISH&system=NETA&7AServer=N600LD&rbPath=https://www1.steroyalbank.com/cgi-bin/rbaccess/rbunxcgi&siteNavCss=https://www1.steroyalbank.com/N600/css/rbcSiteNav_1024Mega.css&siteNavJs=https%3a%2f%2fwww1.steroyalbank.com%2fcgi-bin%2frbaccess%2frbunxcgi%3fF22%3d4WN600S%267ASERVER%3dN601LD%26LANGUAGE%3dENGLISH%267ASCRIPT%3d%2fWebUI%2fNavigation%2fHeaderFooter&titleHeader=Navigation Header&titleMenu=Menu&titleFooter=Footer&requestTime=739307.09:41:26.9978912&refId=MPMVeEXLPHcZcoJgQCIrdA%253d%253d&multex=0&showlevel2=no&NETA=1&DSOL=1&WM=1&IB=0&HOME=0&rollover=1&xtid=RBC:68f5337f833176340076346a370035003201&xbrand=NETA&LOGICALSESSID=TQGzZyBQFSi.ZxAwAAAUMQAAeH4CAA__&RBCAPI=STE_ENV2&HSBCStatus=1; NETA=title=RBC+Direct+Investing+Online+Investing+Services+provided+by+RBC+Financial+Group&prefs=YYY340_monHm8a%2fx6mk7uuxCjR01gVLK7%2bYuElAo%2b0EmAhL5MOSOtyKhXehH79%2fQcAsZ4rmHe4OyMBjTNOGvv5GyEgFP4NcMsNUnkRzXGqfBaAFEI4%3d; 3MSOUT=ISAM; AMWEBJCT\u0021%2Fmga\u0021AACJSID1=0000czlkI124C-jeTR8JxI_f4AT:729e029e-f15b-47eb-8156-02d4ccfc7c2d:7cfb083c-148b-4d40-9d07-b0ffe67f979a; AMWEBJCT\u0021%2Fmga\u00213MLSEC=TQGzZyBQFSi.ZxAwAAAUMQAAeH4CAA__; PD-S-DI-SESSION-ID=1_XPLkwrWyg2sJ9Skid9m7a0AOfFg2ArAsogNxhgYArIoZR/ukM44=_AAAAAAA=_tAGOlAwfqhQBjgqWCPBOjRdd5Ko=; PPAGE=SessionSync; markit-token=000e6utyy5fV2GBaIkPB5Za1Ov6W; _ga_22PRMSS=GS1.1.1740580885.62.1.1740580986.0.0.143775959; dtSa=true%7CC%7C-1%7CdTMasked_%7Ct-0%7C1740580986107%7C580928017_12%7Chttps%3A%2F%2Fwww1.steroyalbank.com%2Fcgi-bin%2Frbaccess%2Frbunxcgi%3FF22%3D4WN600S%267ASERVER%3DN600LD%267ASCRIPT%3D%2FWebUI%2FSearch%2FDetailedQuoteStock%26s%3DPLTR%26c%3DUS%7C%7C%7C%2FOptions%7C%7C%2Fcgi-bin%2Frbaccess%2Frbunxcgi%7C1740580927659%7C%7Ci1%5Esk0%5Esh0%5Est1; RBCXsrf=mtbFowLUHNBznjI0Sv_sQg7nEKi2FIPt1INJzs1FZigsVm3ZyWZdesxk3lY01o4E66j3G3KTeYaxVK41H71wm1f7YHe4tdTxqYzqynOJkOQ1:tJgC0-N5k7toAn3A49bhGO4EK3sOqOm531ESI50xDJuR4zeW2UA93tsyGujw8qRySuZmV8T0h3eoEVuJgkGaq44qkBWc5lLReLjMFJyg0c3FwzonvGeVewLnT4OjJM2ts8rtwB6mhSnnZAYsIB0qXA2; _uetsid=bc793bb0f44f11ef9f823bf1467fcbd0|1ms58hr|2|ftr|0|1883; OptanonConsent=isGpcEnabled=0&datestamp=Wed+Feb+26+2025+09%3A43%3A11+GMT-0500+(Eastern+Standard+Time)&version=202406.1.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=c2f7bf06-1daf-4cad-a6eb-e2e6820a2d88&interactionCount=1&isAnonUser=1&landingPath=NotLandingPage&groups=1%3A1%2C2%3A1%2C3%3A1%2C4%3A1&AwaitingReconsent=false&intType=3&geolocation=CA%3BON; _ga_7JWHW4RRHN=GS1.1.1740580877.63.1.1740580991.0.0.0; DI-XSRF-TOKEN=E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855; _uetvid=af22a9f0b70511efbea39de1409ba7f1|17x0kxv|1740580992233|5|1|bat.bing.com/p/insights/c/l; dtPC=15$580990115_88h-vFLVFNKGAFCTCKRTKMWMPJKKKPPAHUAME-0e0; rxvt=1740582816145|1740580888519; F100=1/WF4/Ic3MUdiwod2tvef-o4CFtdRkjjiiNAFBzwS2sDtXdhDkilgDUrMRIl35Y3TM6PIoeFqWI8nFJ7YvH4yB5YAK8A__/CgAAAA__/DI/PB; F199=F4-005E2C-20250226094335993' \
|
||||||
|
-H 'priority: u=1, i' \
|
||||||
|
-H 'referer: https://www1.steroyalbank.com/cgi-bin/rbaccess/rbunxcgi?F22=4WN600S&7ASERVER=N601LD&LANGUAGE=ENGLISH&7ASCRIPT=/WebUI/OrderEntry/OptionOrderEntryForm&r=5f69iul5qkK87QC8XghpXw' \
|
||||||
|
-H 'sec-ch-ua: "Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"' \
|
||||||
|
-H 'sec-ch-ua-mobile: ?0' \
|
||||||
|
-H 'sec-ch-ua-platform: "Windows"' \
|
||||||
|
-H 'sec-fetch-dest: empty' \
|
||||||
|
-H 'sec-fetch-mode: cors' \
|
||||||
|
-H 'sec-fetch-site: same-origin' \
|
||||||
|
-H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0' \
|
||||||
|
-H 'x-requested-with: XMLHttpRequest'
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
https://www.rbcinsight.com/wm?user_id=testwmadmin&user_password=password&user_tier=WSOD_WM_Admin
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
https://www.rbcinsight.com/wm/?user_id=testcsadmin&user_password=password&user_tier=WSOD_CS_Admin
|
||||||
|
|
||||||
|
https://www.rbcinsight.com/wm/?YYY343_zVOGfVmV1QBKKRhS0soIaD4VxsXkWfL7llkuRZKfmx7oQ8MnNSkkFdHDV0VCiUAH+Ism0gaRbZPAC0xqYF5gHChKJoiYk9978UUZPk1psE+e0zB33Q1A+2dQXUQakYCR
|
||||||
1
src/scratchpad/random notes/id_ed25519.pub
Normal file
1
src/scratchpad/random notes/id_ed25519.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKH7+YB3WLYf6gsQFpi/1IVgCVac+kiZFMSHyghi3CZb azuread\gregjacobs@CF-2MQ4380J51
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
if we are looking recognia score its probably an index
|
||||||
|
we never considered the asset class in symbolLookupMiddleware
|
||||||
|
- Will fix the etf in DJIA index
|
||||||
|
_buildUpSecuritiesRequest not relivant for indices so we need a new function that passes in SYMBOL:INDEX which we can use the asset class
|
||||||
|
|
||||||
|
recogniaScoreIndices
|
||||||
418
src/scratchpad/random notes/impact analysis - api update.txt
Normal file
418
src/scratchpad/random notes/impact analysis - api update.txt
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
Home - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH#/Home
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767649041627
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- rbc-xref
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbols-and-countries
|
||||||
|
|
||||||
|
Holdings - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Holdings/HoldingsHome#/currency
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Holdings/undefined/rbc-preferences/v1/credentials?v=1767649968556
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767649968916
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Performance - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/App_N600/Portfolio.mvc/Performance/DI/en/2c8b3649de3596349140336235e40000360f?IB=0
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650015823
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Income Projection - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH#/IncomeProjection
|
||||||
|
- rbc-income-projection
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-income-projection/v1/symbols-dividend-income?culture=en-US¤cy=cad
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-income-projection/v1/income-estimated-chart?culture=en-US&width=1301&height=336¤cy=cad
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650049340
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Alerts - https://wwwx3.steroyalbank.com/investing/markets/alerts.asp?YYY340_E/EpW74TR26WKajtT3E6K9wrBbidudGgNBKzoc6ms2g2ZkrEePC5eOvy49hw22ACZ+/QVg6uzA0ua1x24XO/6pl/1IUfNSNmjgrxAdmsjHUNEokSZN6aYIQmO3dvnQ32rrhVHz0rxoucQEEANqBanQTrn5YYemF9jD0Ezy3TfBQRFf6f6maighabU5UHmxj1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/investing/markets/undefined/rbc-preferences/v1/credentials?v=1767650125045
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650125401
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Watchlists - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Watchlist?_gl=1*1vv1k89*_gcl_au*NTI0NDgxMTcyLjE3NjY3NzYyNTY.*_ga*MTIwOTA4NDg4Ni4xNzU4MTIyODYz*_ga_7JWHW4RRHN*czE3Njc2NDcyODIkbzM4JGcxJHQxNzY3NjUwMjU4JGo0NyRsMCRoMA..#/quote
|
||||||
|
- rbc-direct-investing
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=coachmark_banner_com_markit_streaming_watchlists_app
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=coachmark_banner_com_markit_edit_watchlists_app
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=di_mw_streaming_enabled
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2460454554&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3759045861&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3818335228&en=dqphgfhl&end=1
|
||||||
|
- rbc-direct-investing-detailed-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=coachmark_banner_com_markit_streaming_watchlists_app
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=coachmark_banner_com_markit_edit_watchlists_app
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=di_mw_streaming_enabled
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2460454554&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3759045861&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3818335228&en=dqphgfhl&end=1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/undefined/rbc-preferences/v1/credentials?v=1767650260460
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650261047
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=mwl_selected_list&1767650262599
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/watchlist/68C8CB58-CA4F-4886-86E3-461A6A6583B6
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/alerts
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2460454554&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3759045861&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3818335228&en=dqphgfhl&end=1
|
||||||
|
- rbc-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&origin=watchlist&validateXref=true
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2460454554&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3759045861&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3818335228&en=dqphgfhl&end=1
|
||||||
|
- rbc-xref
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbols
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2460454554&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3759045861&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3818335228&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
Portfolio Analyzer - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Containers/PortfolioAnalyzer?_gl=1*lhmeis*_gcl_au*NTI0NDgxMTcyLjE3NjY3NzYyNTY.*_ga*MTIwOTA4NDg4Ni4xNzU4MTIyODYz*_ga_7JWHW4RRHN*czE3Njc2NDcyODIkbzM4JGcxJHQxNzY3NjUwMzUzJGo1MSRsMCRoMA..#/Accounts/analyze/3D69836F-AE27-4768-85B6-550045FE9E12/RiskReturn
|
||||||
|
- rbc-analyze-and-rebalance
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/quote/getQuote?baseCurrency=CAD"eCurrency=USD
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/shared/getCurrency
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1152387630&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3506925192&en=dqphgfhl&end=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/getPortfolioAccountContainer?name=70FA97B91CBFE5D3CDC3203250D44B931CB70D7C941DA07FF2BB36D377CE4774
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2663471565&en=dqphgfhl&end=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/updateBalanceAndHoldings?containerID=3D69836F-AE27-4768-85B6-550045FE9E12&exchangeRate=1.37945
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/loadGoalById?goalId=3D69836F-AE27-4768-85B6-550045FE9E12
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getAssetAllocation?total=199521.548281
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=615332622&en=dqphgfhl&end=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/smartText/getSmartText?language=EN&tab=A
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/chart/PieChart?pieSize=240&language=en
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2670723749&en=dqphgfhl&end=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getRegionAllocation?prevDayValue=199522
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1294232047&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1292717230&en=dqphgfhl&end=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getSectorAllocation?rollupType=equity&prevDayPortfolioValue=199521.548281
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/smartText/getSmartText?language=EN&tab=S
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=346291902&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3636001054&en=dqphgfhl&end=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/investment-analysis/getHoldingsConcenteration
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=39038303&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2574638252&en=dqphgfhl&end=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/chart/LongTermChart?width=910&height=350
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyze-and-rebalance-api/v1/smartText/getSmartText?language=EN&tab=RI
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=528871255&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3760955482&en=dqphgfhl&end=1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Containers/undefined/rbc-preferences/v1/credentials?v=1767650356450
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650356938
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1152387630&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3506925192&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=615332622&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
Manage My Goals - https://wwwx3.steroyalbank.com/portfoliobuilder/Goals/Manage?YYY340_E/EpW74TR26WKajtT3E6K9wrBbidudGgNBKzoc6ms2g2ZkrEePC5eOvy49hw22ACZ+/QVg6uzA0ua1x24XO/6pl/1IUfNSNmjgrxAdmsjHUNEokSZN6aYIQmO3dvnQ32rrhVHz0rxoucQEEANqBanVQ1NfEZphzc4Mrxgb+nfwYRFf6f6maighabU5UHmxj1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/portfoliobuilder/Goals/undefined/rbc-preferences/v1/credentials?v=1767650408294
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650409401
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Search - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH&_gl=1*qdf7x3*_gcl_au*NTI0NDgxMTcyLjE3NjY3NzYyNTY.*_ga*MTIwOTA4NDg4Ni4xNzU4MTIyODYz*_ga_7JWHW4RRHN*czE3Njc2NDcyODIkbzM4JGcxJHQxNzY3NjUwNDkyJGo2MCRsMCRoMA..#/Trade/Search
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650495599
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Activity - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH&_gl=1*qdf7x3*_gcl_au*NTI0NDgxMTcyLjE3NjY3NzYyNTY.*_ga*MTIwOTA4NDg4Ni4xNzU4MTIyODYz*_ga_7JWHW4RRHN*czE3Njc2NDcyODIkbzM4JGcxJHQxNzY3NjUwNDkyJGo2MCRsMCRoMA..#/Activity
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650495599
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Order Status - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH&_gl=1*qdf7x3*_gcl_au*NTI0NDgxMTcyLjE3NjY3NzYyNTY.*_ga*MTIwOTA4NDg4Ni4xNzU4MTIyODYz*_ga_7JWHW4RRHN*czE3Njc2NDcyODIkbzM4JGcxJHQxNzY3NjUwNDkyJGo2MCRsMCRoMA..#/OrderStatus
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650495599
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Transfer Funds - Transfer Cash - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/FundTransfer/FundTransferOrderEntryForm/ENGLISH?r=_VPzN7XE706QBlhNHaSK-g
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/FundTransfer/FundTransferOrderEntryForm/undefined/rbc-preferences/v1/credentials?v=1767650573063
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650573584
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2350093558&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1080789830&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
Transfer Funds - Transfer Rewards - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/FundTransfer/PointsTransferOrderEntryForm/ENGLISH
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650620825
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
www1.steroyalbank.com/sgw3/secureapp/N600/App_N600/PacInstruction.mvc/PacInstruction/DI/en/2c8b3649de3596349140336235e40000360f?IB=0 - https://www1.steroyalbank.com/sgw3/secureapp/N600/App_N600/PacInstruction.mvc/PacInstruction/DI/en/2c8b3649de3596349140336235e40000360f?IB=0
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650663054
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Transfer Securities - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/ReactUI/?LANGUAGE=ENGLISH#/Transfer/Securities/1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650676710
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Transfer assets from another institution - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Forms/TransferAccount#/transfer
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Forms/undefined/rbc-preferences/v1/credentials?v=1767650697850
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650698298
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
|
||||||
|
MARKETS OVERVIEW - NO FLAGS ENABLED
|
||||||
|
Markets Overview - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Markets
|
||||||
|
- rbc-charting
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-charting/v1/chart/trend/?culture=en-US&timeframe=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-charting/v1/chart/indexPerformance?xid=593253&culture=en-US&timeframe=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-charting/v1/chart/indexPerformance?xid=593933&culture=en-US&timeframe=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-direct-investing
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewIndexPerformanceSelections
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewEventsSelections
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewMarketMoverSelections
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-direct-investing-detailed-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewIndexPerformanceSelections
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewEventsSelections
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewMarketMoverSelections
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-market-events
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-market-events/v1/dividends?country=ca,us,hk,gb,fr,de
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-market-events/v1/my-dividends-events
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-news
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/R66?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/HAL?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/YCP?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/CHV?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/DY6?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/DEX?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/SLL?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/19V?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/PYR?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/XONA?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/ALD?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/B7J1?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/HLBN?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/SHF?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/ILT?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:05:29.043Z
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650714134
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&Date=1767650715677
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/market-movers/markets/interesting-volume?country=de&numberOfRows=15
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&Date=1767650716262
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&origin=watchlist&validateXref=true
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-sector-industry
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-sector-industry/v1/sector-benchmarks?country=ca&changePeriod=5
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
- rbc-xref
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbols
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbols-and-countries
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=217124879&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2736709985&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3518922903&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
|
||||||
|
MARKETS OVERVIEW - FLAGS ENABLED
|
||||||
|
Markets Overview - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Markets
|
||||||
|
- rbc-charting
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-charting/v1/chart/trend/?culture=en-US&timeframe=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-charting/v1/chart/indexPerformance?xid=593253&culture=en-US&timeframe=1
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-charting/v1/chart/indexPerformance?xid=593933&culture=en-US&timeframe=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-direct-investing
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewMarketMoverSelections
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-direct-investing-detailed-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-direct-investing-detailed-quote/1.0/userPreference?preferenceName=marketsOverviewMarketMoverSelections
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-market-events
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-market-events/v1/economics?country=ca
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-market-events/v1/dividends?country=ca
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-market-events/v1/earnings?country=ca
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-news
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/R66?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/HAL?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/YCP?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/CHV?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/DY6?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/DEX?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/SLL?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/19V?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/PYR?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/XONA?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/ALD?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/B7J1?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/HLBN?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/SHF?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/ILT?exchangeCountry=de&articlesPerPage=0&page=1&startDate=2026-01-05T04:59:59.999Z&endDate=2026-01-05T22:06:34.976Z
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-news/v1/news/country/ca
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650782757
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&Date=1767650783300
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/market-movers/markets/interesting-volume?country=de&numberOfRows=15
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&Date=1767650783713
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/593253?1767650784199
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&origin=watchlist&validateXref=true
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&1767650784978
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&1767650784982
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-sector-industry
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-sector-industry/v1/sector-benchmarks?country=ca&changePeriod=5
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
- rbc-xref
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbol/593253?1767650784199
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-xref/v1/symbols
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=38813460&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
Sectors & Industries - https://wwwx3.steroyalbank.com/investing/markets/sectorsIndustries.asp?YYY340_E/EpW74TR26WKajtT3E6K9wrBbidudGgNBKzoc6ms2g2ZkrEePC5eOvy49hw22ACZ+/QVg6uzA0ua1x24XO/6pl/1IUfNSNmjgrxAdmsjHUNEokSZN6aYIQmO3dvnQ32rrhVHz0rxoucQEEANqBanVQ1NfEZphzcBYv/aC3zCoERFf6f6maighabU5UHmxj1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650886580
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Calendar - https://wwwx3.steroyalbank.com/investing/markets/calendar.asp?YYY340_E/EpW74TR26WKajtT3E6K9wrBbidudGgNBKzoc6ms2g2ZkrEePC5eOvy49hw22ACZ+/QVg6uzA0ua1x24XO/6pl/1IUfNSNmjgrxAdmsjHUNEokSZN6aYIQmO3dvnQ32rrhVHz0rxoucQEEANqBanVQ1NfEZphzcFghhpdbibuARFf6f6maighabU5UHmxj1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/investing/markets/undefined/rbc-preferences/v1/credentials?v=1767650900414
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650900711
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
News & Headlines - https://wwwx3.steroyalbank.com/investing/markets/news.asp?YYY340_E/EpW74TR26WKajtT3E6K9wrBbidudGgNBKzoc6ms2g2ZkrEePC5eOvy49hw22ACZ+/QVg6uzA0ua1x24XO/6pl/1IUfNSNmjgrxAdmsjHUNEokSZN6aYIQmO3dvnQ32rrhVHz0rxoucQEEANqBanVQ1NfEZphzcZHOIFOQW7lMRFf6f6maighabU5UHmxj1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/investing/markets/undefined/rbc-preferences/v1/credentials?v=1767650916866
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650917160
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
GICs, Bonds and Other Fixed Income - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/FixedIncome/Home?_gl=1*1sqjgu9*_gcl_au*NTI0NDgxMTcyLjE3NjY3NzYyNTY.*_ga*MTIwOTA4NDg4Ni4xNzU4MTIyODYz*_ga_7JWHW4RRHN*czE3Njc2NDcyODIkbzM4JGcxJHQxNzY3NjUwOTI3JGoxNSRsMCRoMA..#/search
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/FixedIncome/undefined/rbc-preferences/v1/credentials?v=1767650930666
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650931084
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Market Commentary - https://wwwx3.steroyalbank.com/investing/markets/tradingIdeas.asp?YYY340_E/EpW74TR26WKajtT3E6K9wrBbidudGgNBKzoc6ms2g2ZkrEePC5eOvy49hw22ACZ+/QVg6uzA0ua1x24XO/6pl/1IUfNSNmjgrxAdmsjHUNEokSZN6aYIQmO3dvnQ32rrhVHz0rxoucQEEANqBanVQ1NfEZphzctMWCzaZCctERFf6f6maighabU5UHmxj1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650949682
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Technical Analysis - https://wwwx3.steroyalbank.com/investing/markets/technicalAnalysis.asp?YYY340_E/EpW74TR26WKajtT3E6K9wrBbidudGgNBKzoc6ms2g2ZkrEePC5eOvy49hw22ACZ+/QVg6uzA0ua1x24XO/6pl/1IUfNSNmjgrxAdmsjHUNEokSZN6aYIQmO3dvnQ32rrhVHz0rxoucQEEANqBanVQ1NfEZphzcvsUf2bsbiC8RFf6f6maighabU5UHmxj1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://wwwx3.steroyalbank.com/investing/markets/undefined/rbc-preferences/v1/credentials?v=1767650967133
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650967426
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Investor’s Toolkit - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/IdeasHub?_gl=1*173vbm3*_gcl_au*NTI0NDgxMTcyLjE3NjY3NzYyNTY.*_ga*MTIwOTA4NDg4Ni4xNzU4MTIyODYz*_ga_7JWHW4RRHN*czE3Njc2NDcyODIkbzM4JGcxJHQxNzY3NjUwOTc4JGoyNCRsMCRoMA..#/learning
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/undefined/rbc-preferences/v1/credentials?v=1767650980475
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650981091
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
|
Investor’s Toolkit - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/IdeasHub#/tools
|
||||||
|
- rbc-analyst-picklists
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyst-picklists/v1/pick-list/1/count
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyst-picklists/v1/pick-list/2/count
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyst-picklists/v1/pick-list/3/count
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyst-picklists/v1/pick-list/4/count
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-analyst-picklists/v1/pick-list/5/count
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3137990312&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2687575286&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3464974104&en=dqphgfhl&end=1
|
||||||
|
- rbc-curated-research
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-curated-research/v1/global-investment?country=en
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-curated-research/v1/morningstar
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-curated-research/v1/capital-markets
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-curated-research/v1/morningstar/WideMoatFocusIndex
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3137990312&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2687575286&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3464974104&en=dqphgfhl&end=1
|
||||||
|
- rbc-fundamentals
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-fundamentals/v1/upgrades-downgrades?numRows=6&event=U&country=CA
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3137990312&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2687575286&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3464974104&en=dqphgfhl&end=1
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/undefined/rbc-preferences/v1/credentials?v=1767650995008
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=ideasHubTabSelection_screeners
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767650995923
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3137990312&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=2687575286&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=3464974104&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
Screeners - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Screener#/stocks/saved?screen=DIP-12404
|
||||||
|
- rbc-analyst-picklists
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- rbc-curated-research
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- rbc-preferences
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/undefined/rbc-preferences/v1/credentials?v=1767651030897
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767651031472
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=screener_stocks_last_viewed
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/alerts
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=72710905&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1068839176&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=706478196&en=dqphgfhl&end=1
|
||||||
|
- rbc-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&date=1767651034771
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=72710905&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1068839176&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=706478196&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
|
||||||
|
Screeners - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Screener#/etfs/predefined
|
||||||
|
- rbc-analyst-picklists
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- rbc-curated-research
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- rbc-preferences
|
||||||
|
- https://logging-api.markitqa.com/api/250/store/?sentry_key=5caabe930be443ef801059c22aabc35d&sentry_version=7
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/undefined/rbc-preferences/v1/credentials?v=1767651030897
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767651031472
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=screener_stocks_last_viewed
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/alerts
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=72710905&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1068839176&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=706478196&en=dqphgfhl&end=1
|
||||||
|
- rbc-quote
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-quote/v1/multiquote?previousDay=false&date=1767651034771
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=72710905&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=1068839176&en=dqphgfhl&end=1
|
||||||
|
- https://www1.steroyalbank.com/secureapp/N600/WebUI/rb_bf92799cya?type=js3&sn=v_4_srv_-2D66_sn_C8EJC3IN9V92BM6JNV6SADH2QKVAEOKN&svrid=-66&flavor=post&vi=WTOGBCWATCRBOHMIPAGNEGMAHPMWEUBV-0&modifiedSince=1766000123111&bp=3&app=4e442bafb20835bc&crc=706478196&en=dqphgfhl&end=1
|
||||||
|
|
||||||
|
Screeners - RBC Direct Investing - https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/Screener#/funds/predefined
|
||||||
|
- rbc-preferences
|
||||||
|
- https://www1.steroyalbank.com/sgw3/secureapp/N600/WebUI/undefined/rbc-preferences/v1/credentials?v=1767651074223
|
||||||
|
- https://wwwx3.steroyalbank.com/api//rbc-preferences/v1/credentials?v=1767651075353
|
||||||
|
- https://wwwx3.steroyalbank.com/api/rbc-preferences/v1/preference?preferenceName=gww_selected_list
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
kebab left right align dropdown as a fix in PR
|
||||||
|
kebab fix casing on folder to lowercase first word
|
||||||
|
|
||||||
|
should not render trade link comps when is tradable is false
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
more focus on using natural triggers and emits over modifying state directly
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
sync with Jeremy on goals for prof development
|
||||||
2
src/scratchpad/random notes/technical goals.txt
Normal file
2
src/scratchpad/random notes/technical goals.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
technical goals
|
||||||
|
- Code contributions dropped off since GitHub copilot
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
when it emits it calls charts and that resizableChart exists
|
||||||
|
|
||||||
|
991px
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- next check-in plot next 6 months of time off only for Regionals/IC
|
||||||
|
-- Feb 11th Dev Hrs - Decoupled Component Files and Models over Vuex/Pinia
|
||||||
|
-- Improvements to FF to pull in FF that are not listed within web component POC and direct investing frontend
|
||||||
|
--
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
3
src/styles/bootstrap.scss
vendored
Normal file
3
src/styles/bootstrap.scss
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@import 'extended/_variables_extended';
|
||||||
|
@import 'node_modules/bootstrap/scss/bootstrap';
|
||||||
|
@import 'extended/extendedutilities';
|
||||||
24
src/styles/charts.scss
Normal file
24
src/styles/charts.scss
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.chart-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
width: 80%;
|
||||||
|
margin-left: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
text-align: left;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #42b983;
|
||||||
|
padding: 2em;
|
||||||
|
margin: 1em;
|
||||||
|
color: #fff;
|
||||||
|
height: 200px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/styles/extended/_extendedutilities.scss
Normal file
25
src/styles/extended/_extendedutilities.scss
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||||
|
@include media-breakpoint-up($breakpoint) {
|
||||||
|
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||||
|
|
||||||
|
.border#{$infix}-top { border-top: $border-width solid $border-color !important; }
|
||||||
|
.border#{$infix}-right { border-right: $border-width solid $border-color !important; }
|
||||||
|
.border#{$infix}-bottom { border-bottom: $border-width solid $border-color !important; }
|
||||||
|
.border#{$infix}-left { border-left: $border-width solid $border-color !important; }
|
||||||
|
|
||||||
|
.border#{$infix}-top-0 { border-top: 0 !important; }
|
||||||
|
.border#{$infix}-right-0 { border-right: 0 !important; }
|
||||||
|
.border#{$infix}-bottom-0 { border-bottom: 0 !important; }
|
||||||
|
.border#{$infix}-left-0 { border-left: 0 !important; }
|
||||||
|
|
||||||
|
.border#{$infix}-x {
|
||||||
|
border-left: $border-width solid $border-color !important;
|
||||||
|
border-right: $border-width solid $border-color !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border#{$infix}-y {
|
||||||
|
border-top: $border-width solid $border-color !important;
|
||||||
|
border-bottom: $border-width solid $border-color !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/styles/extended/_variables_extended.scss
Normal file
1
src/styles/extended/_variables_extended.scss
Normal file
@@ -0,0 +1 @@
|
|||||||
|
$font-family-sans-serif: "Roboto", Arial, sans-serif !important;
|
||||||
178
src/styles/rbc-global-color.scss
Normal file
178
src/styles/rbc-global-color.scss
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
|
||||||
|
// Global Styles / Colour by code only
|
||||||
|
|
||||||
|
|
||||||
|
// - Core Colour
|
||||||
|
|
||||||
|
$dark-blue: #002750;
|
||||||
|
$dark-blue-tint-1: #003168;
|
||||||
|
$rbc-blue: #0051A5;
|
||||||
|
$rbc-blue-tint: #4C7AA3;
|
||||||
|
$rbc-blue-tint-1: #006AC3;
|
||||||
|
$rbc-blue-tint-2: #73B0E3;
|
||||||
|
$rbc-blue-tint-3: #C3E2FA;
|
||||||
|
$rbc-blue-tint-4: #E3F4FF;
|
||||||
|
$rbc-blue-tint-5: #F5FCFF;
|
||||||
|
$rbc-blue-tint-6: #E7EDF2;
|
||||||
|
$ocean:#0991DA;
|
||||||
|
$rbc-blue-tint-7: #00437d;
|
||||||
|
|
||||||
|
$dark-yellow: #FBAA26;
|
||||||
|
$dark-yellow-tint-1: #FFBA00;
|
||||||
|
$rbc-yellow: #FEDF01;
|
||||||
|
$rbc-yellow-tint-1: #FEEF80;
|
||||||
|
$rbc-yellow-tint-2: #FFF7BF;
|
||||||
|
$rbc-yellow-tint-3: #FFFCE5;
|
||||||
|
$rbc-yellow-tint-4: #F0EDDC;
|
||||||
|
$warm-yellow: #FFC72C;
|
||||||
|
|
||||||
|
$black-tint-2: #252525;
|
||||||
|
$black-tint-1:#1F1F1F;
|
||||||
|
$dark-grey-1: #444444;
|
||||||
|
$grey: #585858;
|
||||||
|
$grey-tint-1: #6F6F6F;
|
||||||
|
$grey-tint-2: #919191;
|
||||||
|
$grey-tint-3: #B3B3B3;
|
||||||
|
$grey-light-tint-4: #E0E0E0;
|
||||||
|
$grey-light-tint-3: #EAEAEA;
|
||||||
|
$grey-light-tint-2: #F3F4F5;
|
||||||
|
$grey-light-tint-1: #FAFAFA;
|
||||||
|
|
||||||
|
// Black & White
|
||||||
|
|
||||||
|
$black: #000000;
|
||||||
|
$white: #FFFFFF;
|
||||||
|
|
||||||
|
// Accent Colours - Bright
|
||||||
|
|
||||||
|
$violet-dark: #1D1934;
|
||||||
|
$violet-dark-tint-1:#2E2851;
|
||||||
|
$violet: #493D63;
|
||||||
|
$violet-tint-1:#C5A5DA;
|
||||||
|
$violet-tint-2: #E3D3F4;
|
||||||
|
$violet-tint-3: #F6F1FC;
|
||||||
|
|
||||||
|
$wine-dark:#45111A;
|
||||||
|
$wine-dark-tint-1: #6E1A3B;
|
||||||
|
$wine: #8B214B;
|
||||||
|
$wine-tint-1: #F39EC0;
|
||||||
|
$wine-tint-2:#F6CDDD;
|
||||||
|
$wine-tint-3: #FFEBF7;
|
||||||
|
|
||||||
|
$warm-red-dark: #B91A0E;
|
||||||
|
$warm-red-dark-tint-1: #D32619;
|
||||||
|
$warm-red: #F93F26;
|
||||||
|
$warm-red-tint-1: #FC9F92;
|
||||||
|
$warm-red-tint-2: #FDCFC9;
|
||||||
|
$warm-red-tint-3: #FEEBE9;
|
||||||
|
$warm-red-dark-shade-1: #B20023;
|
||||||
|
|
||||||
|
$sun-dark: #9E5406;
|
||||||
|
$sun-dark-tint-1: #CC700F;
|
||||||
|
$sun: #FCA311;
|
||||||
|
$sun-tint-1: #FDD188;
|
||||||
|
$sun-tint-2: #FEE8C3;
|
||||||
|
$sun-tint-3: #FFF6E7;
|
||||||
|
|
||||||
|
$pear-dark:#726C1A;
|
||||||
|
$pear-dark-tint-1: #978F28;
|
||||||
|
$pear: #D6CE48;
|
||||||
|
$pear-tint-1: #EAE6A4;
|
||||||
|
$pear-tint-2: #F5F3D1;
|
||||||
|
$pear-tint-3: #FBFAEC;
|
||||||
|
|
||||||
|
$apple-dark:#616F03;
|
||||||
|
$apple-dark-tint-1: #7E9006;
|
||||||
|
$apple: #AABA0A;
|
||||||
|
$apple-tint-1: #D4DC84;
|
||||||
|
$apple-tint-2: #EAEEC2;
|
||||||
|
$apple-tint-3: #F6F8E6;
|
||||||
|
|
||||||
|
$lime-shade-1: #3C9D4D;
|
||||||
|
$lime-shade-2: #008000;
|
||||||
|
|
||||||
|
$seaweed-dark: #416866;
|
||||||
|
$seaweed-dark-tint-1: #4C7775;
|
||||||
|
$seaweed: #588886;
|
||||||
|
$seaweed-tint-1: #ABC3C2;
|
||||||
|
$seaweed-tint-2: #E3EBEB;
|
||||||
|
$seaweed-tint-3: #F2F6F6;
|
||||||
|
|
||||||
|
$teal-dark: #0D6A6E;
|
||||||
|
$teal-dark-tint-1: #088C91;
|
||||||
|
$teal: #00AEB5;
|
||||||
|
$teal-tint-1: #88DDE0;
|
||||||
|
$teal-tint-2: #B9F8FA;
|
||||||
|
$teal-tint-3: #E5FEFF;
|
||||||
|
|
||||||
|
$sky-dark: #236E9A;
|
||||||
|
$sky-dark-tint-1: #3589BB;
|
||||||
|
$sky: #51B5E0;
|
||||||
|
$sky-tint-1: #A8DAEF;
|
||||||
|
$sky-tint-2: #D3ECF7;
|
||||||
|
$sky-tint-3: #EDF7FC;
|
||||||
|
|
||||||
|
// - Accent Colours - Neutral
|
||||||
|
|
||||||
|
$tundra-dark: #466C86;
|
||||||
|
$tundra-dark-tint-1: #6595A9;
|
||||||
|
$tundra: #87AFBF;
|
||||||
|
$tundra-tint-1: #C3D7DF;
|
||||||
|
$tundra-tint-2: #E1EBEF;
|
||||||
|
$tundra-tint-3: #F3F7F8;
|
||||||
|
|
||||||
|
$carbon-dark: #50585F;
|
||||||
|
$carbon-dark-tint-1: #6B7782;
|
||||||
|
$carbon: #899299;
|
||||||
|
$carbon-tint-1: #C4C8CC;
|
||||||
|
$carbon-tint-2: #E9EAEC;
|
||||||
|
$carbon-tint-3: #F6F6F7;
|
||||||
|
|
||||||
|
$warm-grey-dark: #70665B;
|
||||||
|
$warm-grey-dark-tint-1: #998E7D;
|
||||||
|
$warm-grey: #C1B5A5;
|
||||||
|
$warm-grey-tint-1: #E0DAD2;
|
||||||
|
$warm-grey-tint-2: #EFECE8;
|
||||||
|
$warm-grey-tint-3: #F9F7F6;
|
||||||
|
|
||||||
|
$beige-dark: #756738;
|
||||||
|
$beige-dark-tint-1: #9D8E54;
|
||||||
|
$beige: #B8A970;
|
||||||
|
$beige-tint-1: #DBD4B7;
|
||||||
|
$beige-tint-2: #EEEADD;
|
||||||
|
$beige-tint-3: #F8F6F0;
|
||||||
|
|
||||||
|
$brown-dark: #543B28;
|
||||||
|
$brown-dark-tint-1: #6A4B33;
|
||||||
|
$brown: #906646;
|
||||||
|
$brown-tint-1: #E7C3A8;
|
||||||
|
$brown-tint-2: #FDE5D2;
|
||||||
|
$brown-tint-3: #FFF3EA;
|
||||||
|
$beige: #B8A970;
|
||||||
|
|
||||||
|
// - Alerts
|
||||||
|
$alert-success: #097B24;;
|
||||||
|
$alert-error: #B91A0E;
|
||||||
|
$alert-warning: #FFBA00;
|
||||||
|
$alert-info: #456B86;
|
||||||
|
$alert-border-color: #6F6F6F;
|
||||||
|
|
||||||
|
$rw-gold-dark:#543F12;
|
||||||
|
$rw-gold-dark-tint-1: #694F15;
|
||||||
|
$rw-gold-dark-tint-2: #7E5F1B;
|
||||||
|
$rw-gold: #936F1F;
|
||||||
|
$rw-gold-tint-1: #A87F23;
|
||||||
|
$rw-gold-tint-2: #BD8F28;
|
||||||
|
$rw-gold-tint-3: #D29F2C;
|
||||||
|
|
||||||
|
$rw-snipe: #FFE474;
|
||||||
|
|
||||||
|
$rw-black-tint-1: #202225;
|
||||||
|
$rw-dark-grey-1: #373B41;
|
||||||
|
$rw-grey: #4F545C;
|
||||||
|
$rw-grey-tint-1: #676D77;
|
||||||
|
$rw-grey-tint-2: #7F8691;
|
||||||
|
$rw-grey-tint-3: #9BA0A9;
|
||||||
|
$rw-grey-light-tint-3: #B6BAC1;
|
||||||
|
$rw-grey-light-tint-2: #D2D4D8;
|
||||||
|
$rw-grey-light-tint-1: #EDEEF0;
|
||||||
40
src/styles/rbc-global-font.scss
Normal file
40
src/styles/rbc-global-font.scss
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
@import "./rbc-global-color.scss";
|
||||||
|
|
||||||
|
|
||||||
|
//*************** FONT SIZES ********************************/
|
||||||
|
|
||||||
|
$font-size_4px: 0.25rem;
|
||||||
|
$font-size_5px: 0.3125rem;
|
||||||
|
$font-size_6px: 0.375rem;
|
||||||
|
$font-size_7px: 0.4375rem;
|
||||||
|
$font-size_8px: 0.5rem;
|
||||||
|
$font-size_9px: 0.5625rem;
|
||||||
|
$font-size_10px: 0.625rem;
|
||||||
|
$font-size_11px: 0.6875rem;
|
||||||
|
$font-size_12px: 0.75rem;
|
||||||
|
$font-size_13px: 0.8125rem;
|
||||||
|
$font-size_14px: 0.875rem;
|
||||||
|
$font-size_15px: 0.9375rem;
|
||||||
|
$font-size_16px: 1rem;
|
||||||
|
$font-size_17px: 1.0625rem;
|
||||||
|
$font-size_18px: 1.125rem;
|
||||||
|
$font-size_19px: 1.1875rem;
|
||||||
|
$font-size_20px: 1.25rem;
|
||||||
|
$font-size_21px: 1.3125rem;
|
||||||
|
$font-size_22px: 1.375rem;
|
||||||
|
$font-size_23px: 1.4375rem;
|
||||||
|
$font-size_24px: 1.5rem;
|
||||||
|
$font-size_25px: 1.5625rem;
|
||||||
|
$font-size_26px: 1.5625rem;
|
||||||
|
$font-size_27px: 1.6875rem;
|
||||||
|
$font-size_28px: 1.75rem;
|
||||||
|
$font-size_30px: 1.875rem;
|
||||||
|
$font-size_32px: 2rem;
|
||||||
|
$font-size_34px: 2.125rem;
|
||||||
|
$font-size_36px: 2.25rem;
|
||||||
|
$font-size_38px: 2.375rem;
|
||||||
|
$font-size_40px: 2.5rem;
|
||||||
|
|
||||||
|
$font-family-roboto: 'Roboto', sans-serif;
|
||||||
|
$font-family-arial: 'Arial', sans-serif;
|
||||||
|
$font-family-rbc: 'RBC MS Display', 'Roboto', sans-serif;
|
||||||
62
src/styles/rbc-global-functions.scss
Normal file
62
src/styles/rbc-global-functions.scss
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
@import "@bootstrap/scss/_functions.scss";
|
||||||
|
@function strip-unit($num) {
|
||||||
|
@return divide($num, $num * 0 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function -zf-to-rem($value, $base: null) {
|
||||||
|
// Check if the value is a number
|
||||||
|
@if type-of($value) != "number" {
|
||||||
|
@if $unit-warnings {
|
||||||
|
@warn inspect($value) + ' was passed to rem-calc(), which is not a number.';
|
||||||
|
}
|
||||||
|
@return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform em into rem if someone hands over 'em's
|
||||||
|
@if unit($value) == "em" {
|
||||||
|
$value: strip-unit($value) * 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate rem if units for $value is not rem or em
|
||||||
|
@if unit($value) != "rem" {
|
||||||
|
$value: divide(strip-unit($value), strip-unit($base)) * 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn 0rem into 0
|
||||||
|
@if $value == 0rem {
|
||||||
|
$value: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function rem-calc($values, $base: null) {
|
||||||
|
$rem-values: ();
|
||||||
|
$count: length($values);
|
||||||
|
|
||||||
|
// If no base is defined, defer to the global font size
|
||||||
|
@if $base == null {
|
||||||
|
$base: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the base font size is a %, then multiply it by 16px
|
||||||
|
// This is because 100% font size = 16px in most all browsers
|
||||||
|
@if unit($base) == "%" {
|
||||||
|
$base: divide($base, 100%) * 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using rem as base allows correct scaling
|
||||||
|
@if unit($base) == "rem" {
|
||||||
|
$base: strip-unit($base) * 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $count == 1 {
|
||||||
|
@return -zf-to-rem($values, $base);
|
||||||
|
}
|
||||||
|
|
||||||
|
@for $i from 1 through $count {
|
||||||
|
$rem-values: append($rem-values, -zf-to-rem(nth($values, $i), $base));
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $rem-values;
|
||||||
|
}
|
||||||
113
src/styles/rbc-global-icons.scss
Normal file
113
src/styles/rbc-global-icons.scss
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
@import "rbc-global-variables.scss";
|
||||||
|
|
||||||
|
.no-icon:before {
|
||||||
|
content: '--';
|
||||||
|
}
|
||||||
|
|
||||||
|
$caret-thickness: 2px;
|
||||||
|
$caret-border-radius: ($caret-thickness)*0.5;
|
||||||
|
$caret-thickness-lg: 3px;
|
||||||
|
$caret-size-lg: 11px;
|
||||||
|
$caret-size: 9px;
|
||||||
|
$caret-size-sm: 7px;
|
||||||
|
|
||||||
|
.css-icon {
|
||||||
|
|
||||||
|
&.css-icon-caret {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: $caret-size;
|
||||||
|
height: $caret-size;
|
||||||
|
-webkit-border-radius: 50%;
|
||||||
|
-moz-border-radius: 50%;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content:"";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: inherit;
|
||||||
|
height: $caret-size;
|
||||||
|
width: $caret-thickness;
|
||||||
|
background-color: $text-black-tertiary;
|
||||||
|
|
||||||
|
-moz-border-radius: $caret-border-radius;
|
||||||
|
-ms-border-radius: $caret-border-radius;
|
||||||
|
-o-border-radius: $caret-border-radius;
|
||||||
|
-webkit-border-radius: $caret-border-radius;
|
||||||
|
border-radius: $caret-border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content:"";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: inherit;
|
||||||
|
height: $caret-thickness;
|
||||||
|
width: $caret-size;
|
||||||
|
background-color: $text-black-tertiary;
|
||||||
|
|
||||||
|
-moz-border-radius: $caret-border-radius;
|
||||||
|
-ms-border-radius: $caret-border-radius;
|
||||||
|
-o-border-radius: $caret-border-radius;
|
||||||
|
-webkit-border-radius: $caret-border-radius;
|
||||||
|
border-radius: $caret-border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.css-icon-caret-up {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
&.css-icon-caret-down {
|
||||||
|
transform: rotate(-135deg);
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
&.css-icon-caret-right {
|
||||||
|
transform: rotate(135deg);
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
&.css-icon-caret-left {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.recognia-icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
position: relative;
|
||||||
|
&.icon-bullish-event {
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-bottom: 14px solid $change-positive;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
&.icon-bearish-event {
|
||||||
|
border: 8px solid transparent;
|
||||||
|
border-bottom-color: $change-negative;
|
||||||
|
top: -5px;
|
||||||
|
&::after {
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
left: -8px;
|
||||||
|
top: 8px;
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
border: 8px solid transparent;
|
||||||
|
border-top-color: $change-negative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.icon-other-event,
|
||||||
|
&.icon-neutral-event {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
background: $chart-ext-carbon;
|
||||||
|
border-radius: 14px;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
212
src/styles/rbc-global-miscellaneous.scss
Normal file
212
src/styles/rbc-global-miscellaneous.scss
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
.focus-outline {
|
||||||
|
border: $border-1;
|
||||||
|
background : $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.focus-inline {
|
||||||
|
border: $border-2;
|
||||||
|
background : $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-border {
|
||||||
|
border: $border-1;
|
||||||
|
background : $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border_1 {
|
||||||
|
border: $border-1;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border_2 {
|
||||||
|
border: $border-2;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
border: $border-1;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta {
|
||||||
|
border: $border-2;
|
||||||
|
background : $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-active {
|
||||||
|
border: $border-3;
|
||||||
|
background : $rbc-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion {
|
||||||
|
border: $border-1;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
border: $border-3;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
border: $border-3;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-header {
|
||||||
|
border: $border-1;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-body {
|
||||||
|
border: $border-1;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell {
|
||||||
|
border: $border-1;
|
||||||
|
background : $grey-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Containers
|
||||||
|
.box-container {
|
||||||
|
border: $border_1 solid $grey-light-tint-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************** P & CB Typography*************************/
|
||||||
|
|
||||||
|
// - PADDING
|
||||||
|
|
||||||
|
.padding_0 {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_2 {
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_3 {
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_4 {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_left_0 {
|
||||||
|
padding-left : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_left_3 {
|
||||||
|
padding-left : 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_left_5 {
|
||||||
|
padding-left : 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_left_10 {
|
||||||
|
padding-left : 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_left_14 {
|
||||||
|
padding-left : 14px;
|
||||||
|
}
|
||||||
|
// @TODO: update rbc-global-miscellaneous import from UniversalSearch.ce.vue upon file removal
|
||||||
|
.padding_left_16 {
|
||||||
|
padding-left : 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_right_0 {
|
||||||
|
padding-right : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_right_5 {
|
||||||
|
padding-right : 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_right_8 {
|
||||||
|
padding-right : 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_right_12 {
|
||||||
|
padding-right : 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_right_15 {
|
||||||
|
padding-right : 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_right_16 {
|
||||||
|
padding-right : 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_right_10 {
|
||||||
|
padding-right : 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_top_4 {
|
||||||
|
padding-top : 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_top_6 {
|
||||||
|
padding-top : 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_top_8 {
|
||||||
|
padding-top : 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_top_10 {
|
||||||
|
padding-top : 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_bottom_3 {
|
||||||
|
padding-bottom : 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_bottom_8 {
|
||||||
|
padding-bottom : 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding_bottom_15 {
|
||||||
|
padding-bottom : 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
@include paragraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@include heading-xl_low-emphasis;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@include heading-lg_low-emphasis;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@include heading-md_low-emphasis;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
@include heading-sm_low-emphasis;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
@include heading-xs;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
@include heading-2xs;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@include uiText-font;
|
||||||
|
@include paragraph-a;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
@include uiText-font;
|
||||||
|
@include paragraph-strong;
|
||||||
|
}
|
||||||
694
src/styles/rbc-global-mixins.scss
Normal file
694
src/styles/rbc-global-mixins.scss
Normal file
@@ -0,0 +1,694 @@
|
|||||||
|
@import "./rbc-global-color.scss";
|
||||||
|
|
||||||
|
@mixin standard-outline($color, $size: 8px) {
|
||||||
|
&:after {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
top: -$size/2;
|
||||||
|
left: -$size/2;
|
||||||
|
height: calc(100% + $size);
|
||||||
|
width: calc(100% + $size);
|
||||||
|
border: 1px solid $color;
|
||||||
|
border-radius: inherit;
|
||||||
|
pointer-events: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin modal-layout($maxWidth, $maxHeight, $modal-spacing: 60px) {
|
||||||
|
max-width: $maxWidth;
|
||||||
|
max-height: $maxHeight;
|
||||||
|
width: calc(100vw - $modal-spacing);
|
||||||
|
height: calc(100vw - $modal-spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin backdrop-layout {
|
||||||
|
background-color: $black-tint-2;
|
||||||
|
opacity: 0.5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin placeholderStyle {
|
||||||
|
color: $text-black-tertiary;
|
||||||
|
font-size: $font-size_13px;
|
||||||
|
font-style: italic;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Good for use with non-native focusable elements like an <p, div, tag> w/ tabindex="-1" used to focus programmatically to make sure and show focus in IE
|
||||||
|
@mixin focusStyling {
|
||||||
|
outline: 1px solid $btn-focus-border;
|
||||||
|
box-shadow: 0px 0px 5px 3px $btn-focus-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - UI TEXT
|
||||||
|
|
||||||
|
@mixin uiText-font {
|
||||||
|
font-family: $font-family-roboto;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-2xs {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_11px;
|
||||||
|
line-height: rem-calc(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-2xs_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_11px;
|
||||||
|
line-height: rem-calc(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-xs {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_12px;
|
||||||
|
line-height: rem-calc(16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-xs_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_12px;
|
||||||
|
line-height: rem-calc(16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-sm {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_14px;
|
||||||
|
line-height: rem-calc(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-sm_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_14px;
|
||||||
|
line-height: rem-calc(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_16px;
|
||||||
|
line-height: rem-calc(24px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_16px;
|
||||||
|
line-height: rem-calc(24px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-lg {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_18px;
|
||||||
|
line-height: rem-calc(28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-lg_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_18px;
|
||||||
|
line-height: rem-calc(28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-xl {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_20px;
|
||||||
|
line-height: rem-calc(28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin uitext-xl_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_20px;
|
||||||
|
line-height: rem-calc(28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - HEADING
|
||||||
|
|
||||||
|
@mixin heading-2xs {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_18px;
|
||||||
|
line-height: rem-calc(28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-xs {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_20px;
|
||||||
|
line-height: rem-calc(28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-sm_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_24px;
|
||||||
|
line-height: rem-calc(32px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-sm {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_24px;
|
||||||
|
line-height: rem-calc(32px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-md_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_28px;
|
||||||
|
line-height: rem-calc(36px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-md {
|
||||||
|
font-size: $font-size_28px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: rem-calc(36px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-lg_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_32px;
|
||||||
|
line-height: rem-calc(40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-lg {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_32px;
|
||||||
|
line-height: rem-calc(40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-xl_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_36px;
|
||||||
|
line-height: rem-calc(44px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin heading-2xl_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_40px;
|
||||||
|
line-height: rem-calc(48px);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - PARAGRAPH
|
||||||
|
|
||||||
|
@mixin paragraph-strong {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph-em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph-a {
|
||||||
|
color: $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph-xs {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_12px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph-sm {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_16px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph-lg {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_18px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph-xl {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_20px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin paragraph-2xl {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_24px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - BIG NUMBER
|
||||||
|
|
||||||
|
@mixin bignumber-xs {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_24px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber-xs_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_24px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber-sm {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_28px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber-sm_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_28px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_32px;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_32px;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber-lg {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_36px;
|
||||||
|
line-height: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber-lg_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_36px;
|
||||||
|
line-height: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber-xl {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: $font-size_40px;
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bignumber-xl_low-emphasis {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: $font-size_40px;
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - COMPONENT SPECIFIC
|
||||||
|
|
||||||
|
@mixin button-sm {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: $font-size_14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin datepicker-day {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: $font-size_14px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin datepicker-year {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: $font-size_16px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin button {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: $font-size_16px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin buttonWithoutBg {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin mobile {
|
||||||
|
@media (max-width: #{$screen-size-xs}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin tab {
|
||||||
|
@media (max-width: #{$screen-size-sm}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xs-break {
|
||||||
|
@media (max-width: #{$screen-size-xs}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin small-break {
|
||||||
|
@media (max-width: #{$screen-size-sm}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin medium-break {
|
||||||
|
@media (max-width: #{$screen-size-md}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin lg-break {
|
||||||
|
@media (max-width: #{$screen-size-lg}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xl-break {
|
||||||
|
@media (max-width: #{$screen-size-xl}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xxl-break {
|
||||||
|
@media (max-width: #{$screen-size-xxl}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xxs-container {
|
||||||
|
@container (max-width: #{$screen-size-xxs}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin link-standard {
|
||||||
|
color: $rbc-blue-tint-1;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $rbc-blue-tint-1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus-visible {
|
||||||
|
color: $rbc-blue;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $rbc-blue !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
fill: $rbc-blue !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
border: none;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: 2px solid $rbc-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: $dark-blue-tint-1;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $dark-blue-tint-1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
fill: $dark-blue-tint-1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled],
|
||||||
|
&[aria-disabled="true"] {
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: none;
|
||||||
|
color: $text-black-tertiary;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $text-black-tertiary !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
fill: $text-black-tertiary !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin button-primary {
|
||||||
|
color: $white;
|
||||||
|
background-color: $rbc-blue-tint-1;
|
||||||
|
border: 2px solid $rbc-blue-tint-1;
|
||||||
|
position: relative;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $btn-prime-hover;
|
||||||
|
border-color: $btn-prime-hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
@include standard-outline($rbc-blue-tint-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: $dark-blue-tint-1;
|
||||||
|
border-color: $dark-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled],
|
||||||
|
&[aria-disabled="true"] {
|
||||||
|
background-color: $grey-light-tint-3;
|
||||||
|
color: $grey-tint-2;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin button-secondary {
|
||||||
|
color: $rbc-blue-tint-1;
|
||||||
|
background-color: $white;
|
||||||
|
border: 2px solid $rbc-blue-tint-1;
|
||||||
|
position: relative;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: $rbc-blue;
|
||||||
|
color: $rbc-blue;
|
||||||
|
background-color: $tundra-tint-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
border: 2px solid $rbc-blue-tint-1;
|
||||||
|
@include standard-outline($rbc-blue-tint-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: $dark-blue-tint-1;
|
||||||
|
border-color: $dark-blue-tint-1;
|
||||||
|
background-color: $tundra-tint-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled],
|
||||||
|
&[aria-disabled="true"] {
|
||||||
|
background-color: $grey-light-tint-3;
|
||||||
|
color: $grey-tint-2;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin button-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
position: relative;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $rbc-blue-tint-1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
:deep(path) {
|
||||||
|
fill: $btn-prime-hover !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
@include standard-outline($btn-prime-hover);
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $btn-prime-hover !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: $dark-blue-tint-1;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $dark-blue-tint-1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled],
|
||||||
|
&[aria-disabled="true"] {
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $grey-tint-2 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin tab-interactions {
|
||||||
|
&:hover {
|
||||||
|
color: $rbc-blue-tint-1;
|
||||||
|
background-color: $tundra-tint-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible, &.focused {
|
||||||
|
background-color: $tundra-tint-3;
|
||||||
|
outline: 1px solid $rbc-blue-tint-1;
|
||||||
|
color: $rbc-blue-tint-1;
|
||||||
|
outline-offset: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active, &:active {
|
||||||
|
color: $rbc-blue-tint-1;
|
||||||
|
border-bottom: 2px solid $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin tag-standard {
|
||||||
|
color: $rbc-blue-tint-1;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid $rbc-blue-tint-1;
|
||||||
|
border-radius: rem-calc(16px);
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $rbc-blue-tint-1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: $rbc-blue;
|
||||||
|
border-color: $rbc-blue;
|
||||||
|
background-color: $sky-tint-3;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $rbc-blue !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: $white;
|
||||||
|
border-color: $white;
|
||||||
|
background-color: $dark-blue-tint-1;
|
||||||
|
outline: 1px solid $dark-blue-tint-1;
|
||||||
|
outline-offset: 1px;
|
||||||
|
|
||||||
|
:deep(path) {
|
||||||
|
fill: $white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all text inside the tag needs to be white when background is dark
|
||||||
|
.text-pos,
|
||||||
|
.text-neg {
|
||||||
|
color: $white !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin line-clamp($lines) {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: $lines;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin card-header-border {
|
||||||
|
align-self: stretch;
|
||||||
|
background: $grey-light-tint-4;
|
||||||
|
border: none;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
height: 1px;
|
||||||
|
margin-bottom: $margin-medium;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin decorative-check-mark-interactions {
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.focused {
|
||||||
|
.check-mark:not([disabled]) {
|
||||||
|
border-color: $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-mark.checked {
|
||||||
|
background-color: $rbc-blue;
|
||||||
|
border-color: $rbc-blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
.check-mark:not([disabled]) {
|
||||||
|
border-color: $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin functional-check-mark-interactions {
|
||||||
|
|
||||||
|
&:hover:not([disabled]),
|
||||||
|
&.focused:not([disabled]) {
|
||||||
|
.check-mark:not([disabled]) {
|
||||||
|
border-color: $rbc-blue-tint-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-mark.checked {
|
||||||
|
background-color: $rbc-blue;
|
||||||
|
border-color: $rbc-blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
.check-mark:not([disabled]) {
|
||||||
|
border-color: $rbc-blue-tint-1;
|
||||||
|
position: relative;
|
||||||
|
@include standard-outline($rbc-blue-tint-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[aria-disabled="true"] {
|
||||||
|
cursor: default;
|
||||||
|
color: $grey-tint-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin fixed-evenly-spaced-flex-row($gap, $numberOfItems) {
|
||||||
|
gap: $gap;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
width: calc((100% / $numberOfItems) - ((($numberOfItems - 1) * $gap) / $numberOfItems));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin text-pos-neg-colors {
|
||||||
|
.text-neg {
|
||||||
|
color: $text-neg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-pos {
|
||||||
|
color: $text-pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
243
src/styles/rbc-global-variables.scss
Normal file
243
src/styles/rbc-global-variables.scss
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
@import "./rbc-global-color.scss";
|
||||||
|
@import "./rbc-global-mixins.scss";
|
||||||
|
@import "./rbc-global-font.scss";
|
||||||
|
@import "./rbc-global-functions.scss";
|
||||||
|
|
||||||
|
//*************** UI & LAYOUT *********************************/
|
||||||
|
|
||||||
|
$margin-2: 0.13em;
|
||||||
|
$margin-4: 0.25em;
|
||||||
|
$margin-small: 8px;
|
||||||
|
$margin-8: 0.5em;
|
||||||
|
$margin-10: 10px;
|
||||||
|
$margin-12: 0.75em;
|
||||||
|
$margin-medium: 20px;
|
||||||
|
$margin-24: 1.5em;
|
||||||
|
$margin-28: 1.75em;
|
||||||
|
$margin-32: 2em;
|
||||||
|
$margin-large: 32px;
|
||||||
|
$margin-xl: 40px;
|
||||||
|
|
||||||
|
// Padding Sizes
|
||||||
|
$padding-xs: 5px;
|
||||||
|
$padding-4: 0.25em;
|
||||||
|
$padding-8: 0.5em;
|
||||||
|
$padding-sm: 10px;
|
||||||
|
$padding-12: 12px;
|
||||||
|
$padding-md: 15px;
|
||||||
|
$padding-16: 1em; // ems scale on the font-size set on the nearest parent, 1 em/rem = 16px at default font-size settings
|
||||||
|
$padding-lg: 20px;
|
||||||
|
$padding-24: 24px;
|
||||||
|
$padding-xl: 30px;
|
||||||
|
$padding-28: 1.75em;
|
||||||
|
$padding-32: 2em;
|
||||||
|
$padding-40: 2.5em; // 40px
|
||||||
|
$padding-48: 3.00em;
|
||||||
|
$padding-62: 3.88em;
|
||||||
|
|
||||||
|
$analyze-page-item-height: 42px;
|
||||||
|
$modal-z-index: 10001;
|
||||||
|
|
||||||
|
//*************** UI & LAYOUT - SCREEN SIZES *********************************/
|
||||||
|
|
||||||
|
$screen-size-xxs : 375px;
|
||||||
|
$screen-size-xs : 575px;
|
||||||
|
$screen-size-sm : 767px;
|
||||||
|
$screen-size-md : 991px;
|
||||||
|
$screen-size-lg : 1183px;
|
||||||
|
$screen-size-xl : 1383px;
|
||||||
|
$screen-size-xxl : 1919px;
|
||||||
|
|
||||||
|
//*************** UI & LAYOUT - MOBILE *********************************/
|
||||||
|
|
||||||
|
$mobile-result-container-height: 44px;
|
||||||
|
$mobile-result-container-max-height: 132px;
|
||||||
|
|
||||||
|
//******************************* All Links **********************/
|
||||||
|
$text-link: #002888; // - Link
|
||||||
|
|
||||||
|
// - Negative/Positive Values
|
||||||
|
$text-neg: #B91A0E; // - Negative
|
||||||
|
$text-pos: #097B24; // - Positive
|
||||||
|
|
||||||
|
// - Panel Colors
|
||||||
|
$text-panel-sub-header: #365D84; // - Panel Sub-Header
|
||||||
|
|
||||||
|
// - Main Text Colors
|
||||||
|
$text-header: #5E7487; // - Header
|
||||||
|
$text-black: #000000; // - Black(Body Copy)
|
||||||
|
$text-black-secondary: #333333; // - Black Secondary
|
||||||
|
$text-black-tertiary: #666666; // - Black Tertiary
|
||||||
|
|
||||||
|
// - Text State Colors
|
||||||
|
$text-disabled: #444; //- Disabled
|
||||||
|
|
||||||
|
//***************************** INTERFACE-SPECIFIC COLORS **************/
|
||||||
|
// - Primary Brand Colors
|
||||||
|
$brand-blue: #002888; // - RBC Blue
|
||||||
|
|
||||||
|
// - Negative / Positive Elements
|
||||||
|
$change-negative: #9C0000; // - Change Negative
|
||||||
|
$change-positive: #005A00; // - Change Positive
|
||||||
|
|
||||||
|
// - Buttons
|
||||||
|
$btn-prime: #002888; // - Button Prime
|
||||||
|
$btn-prime-hover: #0051A5; // - Button Prime Hover
|
||||||
|
$btn-prime-border: #002888; // - Button Prime Border
|
||||||
|
$btn-disabled: #EAEAEA; // - Disabled Button Fill
|
||||||
|
$btn-disabled-border: #B3B3B3; // - Disabled Button Stroke
|
||||||
|
$btn-focus-border: #2C9CDD; // - Focus Border
|
||||||
|
$btn-focus-shadow: #0597FF; // - Focus Shadow
|
||||||
|
|
||||||
|
// - Main Table Colors
|
||||||
|
$table-border: #7E94C2; // - Border
|
||||||
|
$table-options-expanded-border: #00177E;
|
||||||
|
|
||||||
|
// - Practice Account Table
|
||||||
|
$table-practice: #F4F1E5; // - Practice Primary Stripe
|
||||||
|
$table-practice-alt: #E2DFCF; // - Practice Alternating Stripe
|
||||||
|
|
||||||
|
// - Dropdown
|
||||||
|
$dropdown-line-breaks: #999999; // - Line Breaks
|
||||||
|
|
||||||
|
// - Unfilled progress bar
|
||||||
|
$RBC_LightGrey: #D2DADE;
|
||||||
|
|
||||||
|
// - Confirmation
|
||||||
|
$confirmation-pos-border: #005A00; // - Positive Border
|
||||||
|
$confirmation-neg-border: #9C0000; // - Negative Border
|
||||||
|
|
||||||
|
$chart-ext-carbon: #50585F; // - Ext Carbon
|
||||||
|
$chart-reverse-sun: #FCA311; // - Reverse Sun
|
||||||
|
|
||||||
|
/******************** MD Research ************************/
|
||||||
|
|
||||||
|
$technicals_bullish_event: #005a00;
|
||||||
|
$RBC_DarkGrey: #999;
|
||||||
|
$technicals_bearish_event: #b91a0e;
|
||||||
|
|
||||||
|
// - TECHNICALS ICONS
|
||||||
|
|
||||||
|
|
||||||
|
$technicals_other_event: #50585f;
|
||||||
|
$technicals_table_row: #f7f9fa;
|
||||||
|
|
||||||
|
/************************************** P & CB Colour ****************************/
|
||||||
|
|
||||||
|
// - BRANDS
|
||||||
|
$interactive-1: $rbc-blue-tint-1;
|
||||||
|
$interactive-1-hover: $rbc-blue;
|
||||||
|
$interactive-1-active: $dark-blue-tint-1;
|
||||||
|
$interactive-1-text: $white;
|
||||||
|
$interactive-accent: $rbc-yellow;
|
||||||
|
$interactive-accent-hover: $dark-yellow-tint-1;
|
||||||
|
$interactive-accent-active: $dark-yellow;
|
||||||
|
$interactive-accent-text: $black-tint-1;
|
||||||
|
$interactive-opposite: $rbc-yellow;
|
||||||
|
$interactive-opposite-hover: $dark-yellow-tint-1;
|
||||||
|
$interactive-opposite-active: $dark-yellow;
|
||||||
|
$interactive-opposite-text: $black-tint-1;
|
||||||
|
$link: $rbc-blue-tint-1;
|
||||||
|
$link-hover: $rbc-blue;
|
||||||
|
$link-active: $dark-blue-tint-1;
|
||||||
|
$link-opposite: $white;
|
||||||
|
$link-opposite-hover: $white;
|
||||||
|
$link-opposite-active: $white;
|
||||||
|
|
||||||
|
// - TEXT & FOREGROUND
|
||||||
|
$text-default: $black-tint-1;
|
||||||
|
$text-low-emphasis: $grey-tint-1;
|
||||||
|
$text-disabled: $grey-tint-2;
|
||||||
|
$text-opposite-1: $white;
|
||||||
|
$text-opposite-2: $white;
|
||||||
|
|
||||||
|
// - BACKGROUNDS
|
||||||
|
$background-1: $white;
|
||||||
|
$background-2: $grey-light-tint-1;
|
||||||
|
$background-3: $grey-light-tint-2;
|
||||||
|
$background-highlight: $tundra-tint-3;
|
||||||
|
$background-opposite-1: $rbc-blue-tint-1;
|
||||||
|
$background-overlay: $black-tint-1;
|
||||||
|
$background-overlay-inline: $white;
|
||||||
|
$background-page: $white;
|
||||||
|
$background-disabled: $grey-light-tint-3;
|
||||||
|
|
||||||
|
// - BORDERS
|
||||||
|
$border_width_1: 1px;
|
||||||
|
$border_width_2: 2px;
|
||||||
|
$border_width_3: 3px;
|
||||||
|
|
||||||
|
$rounded-circle-1: 1px solid #6F6F6F;
|
||||||
|
$rounded-circle-2: 2px solid #6F6F6F;
|
||||||
|
$rounded-circle-3: 3px solid #6F6F6F;
|
||||||
|
$rounded-circle-4: 4px solid #6F6F6F;
|
||||||
|
|
||||||
|
$border-radius-1: 1px;
|
||||||
|
$border-radius-2: 2px;
|
||||||
|
$border-radius-3: 3px;
|
||||||
|
$border-radius-4: 4px;
|
||||||
|
$border-radius-8: 8px;
|
||||||
|
$border-radius-12: 12px;
|
||||||
|
$border-radius-16: 16px;
|
||||||
|
$border-radius-20: 20px;
|
||||||
|
$border-radius-24: 24px;
|
||||||
|
$border-radius-32: 32px;
|
||||||
|
|
||||||
|
$border-1: $grey-tint-1;
|
||||||
|
$border-2: $black-tint-1;
|
||||||
|
$border-3: $grey-tint-3;
|
||||||
|
$border-4: $grey-light-tint-4;
|
||||||
|
$border-opposite-1: $white;
|
||||||
|
$border-1-grey-light-tint: 1px solid $grey-light-tint-4;
|
||||||
|
|
||||||
|
$border-selected: 0.125rem solid $rbc-blue-tint-1;
|
||||||
|
$border-focus-visible: 0.125rem solid $rbc-blue-tint-1;
|
||||||
|
|
||||||
|
// - BOX SHADOWS
|
||||||
|
$modal-box-shadow: 0px 3.59106px 7.84712px rgba(37, 37, 37, 0.12);
|
||||||
|
$divider-box-shadow: 0.125rem 0px 0.25rem 0px rgba(0, 0, 0, 0.20);
|
||||||
|
$dropdown-box-shadow: 0px 3.591px 7.847px 0px rgba(37, 37, 37, 0.08), 0px 12.062px 26.357px 0px rgba(37, 37, 37, 0.06), 0px 50.25rem 110.5rem 0px rgba(37, 37, 37, 0.04);
|
||||||
|
|
||||||
|
$component-bg-1: $white;
|
||||||
|
$component-bg-2: $sky-tint-3;
|
||||||
|
$component-bg-3: $tundra-tint-2;
|
||||||
|
$component-bg-opposite-1: $white; //transparent
|
||||||
|
|
||||||
|
// - SELECTED STATES
|
||||||
|
$selected-1: $rbc-blue-tint-1;
|
||||||
|
$selected-2: $rbc-blue-tint-4;
|
||||||
|
$selected-opposite-1: $white;
|
||||||
|
|
||||||
|
// - ACTION STATES
|
||||||
|
$action-success : $alert-success;
|
||||||
|
$action-error: $alert-error;
|
||||||
|
$action-warning: $alert-warning;
|
||||||
|
$action-information :$alert-info;
|
||||||
|
$action-neutral: $grey-light-tint-4;
|
||||||
|
|
||||||
|
// - AVATARS
|
||||||
|
$avatar-1: $dark-blue;
|
||||||
|
$avatar-2: $ocean;
|
||||||
|
$avatar-3: $warm-yellow;
|
||||||
|
$avatar-4: $sun;
|
||||||
|
$avatar-5: $beige;
|
||||||
|
$avatar-6: $seaweed;
|
||||||
|
$avatar-8: $warm-grey;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Based on the design: the breakpoints are device breakpoints instead of page breakpoints
|
||||||
|
To get real page breakpoints we use device breakpoints (from the design) - margins
|
||||||
|
*/
|
||||||
|
// TODO: this is a placeholder and it will be adjusted based on the design.
|
||||||
|
$grid-breakpoints: (
|
||||||
|
xxs: 0,
|
||||||
|
xs: 377px,
|
||||||
|
sm: 576px,
|
||||||
|
md: 768px,
|
||||||
|
lg: 992px,
|
||||||
|
xl: 1184px,
|
||||||
|
xxl: 1384px
|
||||||
|
);
|
||||||
|
|
||||||
|
$grid-gap-sm: 1em;
|
||||||
|
$grid-gap: 3em; // 48px
|
||||||
98
src/utils/apiResponseChecker.js
Normal file
98
src/utils/apiResponseChecker.js
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains a script that fetches data from an API and writes it to a file.
|
||||||
|
* The script makes multiple API calls at regular intervals for a specified duration.
|
||||||
|
* The fetched data is appended to separate files based on the data center, user tier, and security symbol.
|
||||||
|
* The script uses Axios for making HTTP requests and the fs module for file operations.
|
||||||
|
*
|
||||||
|
* The script exports a function fetchAndWriteApiData that takes an object with the following properties:
|
||||||
|
* - url: The URL of the API endpoint to fetch data from.
|
||||||
|
* - headers: An object containing the headers to be sent with the request.
|
||||||
|
* - dataCenter: The data center to which the API request should be made.
|
||||||
|
* - userTier: The user tier for which the API request should be made.
|
||||||
|
* - xid: The xid of the security for which the API request should be made.
|
||||||
|
* - symbol: The symbol of the security for which the API request should be made.
|
||||||
|
*
|
||||||
|
* The script also schedules the API calls to be made every 2 minutes for a duration of 4 hours.
|
||||||
|
* The start time and stop time are logged to the console.
|
||||||
|
*/
|
||||||
|
import axios from 'axios';
|
||||||
|
import { promises as fs } from 'fs';
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
const bearerToken = process.env.BEARER_TOKEN;
|
||||||
|
const securities = [
|
||||||
|
{
|
||||||
|
symbol: 'HZU',
|
||||||
|
xid: '19728747'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const dataCenters = ['ptc'];
|
||||||
|
const users = [
|
||||||
|
{
|
||||||
|
userTier: 'GT2',
|
||||||
|
modAccessToken: '{"multex":"Y","active":true,"externalId":"testuser","customerTier":5999,"language":"Y","user_tier":"GT2","token_type":"Bearer","pro":"Y","client_id":"szbv6INGApq0e1Ognvsmzmpq8dGTURTr","realTime":"Y","internalId":"TESTUSER","marketer":"RC","customerType":3879,"levelTwo":"Y","siteId":1614,"exchangeAgreements":"testExchangeAgreements","exp":1689789174}'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
async function fetchAndWriteApiData({url, headers, dataCenter, userTier, xid, symbol}) {
|
||||||
|
try {
|
||||||
|
await axios.get(url, {}, { headers: { ...headers, Authorization: bearerToken } })
|
||||||
|
.then(response => {
|
||||||
|
const datetime = new Date().toISOString();
|
||||||
|
const responseData = response.data.replace(/<!doctype html><html><body><pre>/, '').split('</pre></body></html>');
|
||||||
|
console.error(`${dataCenter} as ${userTier} @ ${datetime} - ${symbol} lastTrade.date:`, JSON.parse(responseData[0])?.data?.lastTrade?.date);
|
||||||
|
const dataToWrite = `Datetime: ${datetime}\nResponse from ${url}:\n${response.data}\n`;
|
||||||
|
return fs.appendFile(`./output/apiResponses/rbc-quote/${dataCenter}_${userTier}_${xid}.txt`, dataToWrite);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// console.log(`Appended response from ${url} to ${dataCenter}_${userTier}.txt`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(`Failed to fetch from ${url} or write to ${dataCenter}_${userTier}_${xid}.txt:`, error);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule the calls every 2 minutes for 4 hours
|
||||||
|
const startTime = new Date().toISOString();
|
||||||
|
const stopTime = new Date(Date.now() + 4 * 60 * 60 * 1000).toISOString();
|
||||||
|
const intervalId = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
// Create an array of promises based on securities array for the each data senter and the users
|
||||||
|
const promises = securities.flatMap(security => {
|
||||||
|
return dataCenters.flatMap(dataCenter => {
|
||||||
|
return users.map(user => {
|
||||||
|
return fetchAndWriteApiData({
|
||||||
|
userTier: user.userTier,
|
||||||
|
dataCenter: dataCenter,
|
||||||
|
xid: security.xid,
|
||||||
|
symbol: security.symbol,
|
||||||
|
url: `https://api.${dataCenter}.services.mdgapp.net/rbc-quote/v1/${security.xid}?realTime=0&..showdebuginfo..=on`, // TODO: showdebuginfo was window based we should use showdebugdata will need to fix in future
|
||||||
|
headers: {
|
||||||
|
'x-mod-access-token': user.modAccessToken
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for all promises to resolve
|
||||||
|
await Promise.all(promises);
|
||||||
|
|
||||||
|
console.log(`All calls completed successfully at ${new Date().toISOString()}`);
|
||||||
|
|
||||||
|
const currentTime = new Date().toISOString();
|
||||||
|
if (currentTime >= stopTime) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
console.log('Interval stopped after 4 hours');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
}, 30 * 1000); // 2 minutes in milliseconds
|
||||||
|
|
||||||
|
console.log('Interval started at:', startTime);
|
||||||
56
src/utils/bookmarkletMaker.js
Normal file
56
src/utils/bookmarkletMaker.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* This script generates a bookmarklet from a JavaScript file.
|
||||||
|
* It reads the JavaScript file, removes any multiline comments, and creates a bookmarklet string.
|
||||||
|
* The bookmarklet can then be used to execute the JavaScript code in a browser.
|
||||||
|
*
|
||||||
|
* Use this to generate a bookmarklet from a JavaScript file in the utils/bookmarklets directory.
|
||||||
|
*
|
||||||
|
* @param {string} filePath - The path to the JavaScript file.
|
||||||
|
* @returns {string} The generated bookmarklet.
|
||||||
|
*/
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import clipboardy from 'clipboardy';
|
||||||
|
|
||||||
|
// Get the file path from command line arguments
|
||||||
|
const filePath = process.argv[2];
|
||||||
|
|
||||||
|
// Read the JavaScript file
|
||||||
|
const jsCode = fs.readFileSync(filePath, 'utf8');
|
||||||
|
|
||||||
|
// Remove multiline comments and single-line comments, but preserve string literals
|
||||||
|
let cleanedCode = jsCode
|
||||||
|
// Remove multiline comments
|
||||||
|
.replace(/\/\*[\s\S]*?\*\//g, '')
|
||||||
|
// Remove single-line comments (but not URLs)
|
||||||
|
.replace(/\/\/.*$/gm, '')
|
||||||
|
// Remove empty lines and extra whitespace
|
||||||
|
.replace(/^\s*\n/gm, '')
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
// Create the bookmarklet
|
||||||
|
const bookmarklet = `javascript:(function() {
|
||||||
|
${cleanedCode}
|
||||||
|
})();`;
|
||||||
|
|
||||||
|
// Validate the generated JavaScript
|
||||||
|
try {
|
||||||
|
// Test if the code is syntactically valid
|
||||||
|
new Function(cleanedCode);
|
||||||
|
console.log('Generated bookmarklet is syntactically valid.');
|
||||||
|
} catch (syntaxError) {
|
||||||
|
console.error('Syntax error in generated code:', syntaxError.message);
|
||||||
|
console.log('Generated code:');
|
||||||
|
console.log(cleanedCode);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the bookmarklet to the clipboard
|
||||||
|
try {
|
||||||
|
clipboardy.writeSync(bookmarklet);
|
||||||
|
console.log('Bookmarklet copied to clipboard successfully.');
|
||||||
|
console.log('Length:', bookmarklet.length, 'characters');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to copy bookmarklet to clipboard:', error);
|
||||||
|
}
|
||||||
12
src/utils/bookmarklets/apiDocs.js
Normal file
12
src/utils/bookmarklets/apiDocs.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the API documentation for a given project API.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*
|
||||||
|
* @param {string} projectAPI - The project API to open the documentation for.
|
||||||
|
*/
|
||||||
|
const projectAPI = prompt("Please enter the project API:");
|
||||||
|
if (projectAPI) {
|
||||||
|
window.open(`https://api.qa.services.mdgapp.net/${projectAPI}/v1/docs`, "_blank").focus();
|
||||||
|
}
|
||||||
33
src/utils/bookmarklets/bmo-gam-auth.js
Normal file
33
src/utils/bookmarklets/bmo-gam-auth.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* BMO GAM Authentication Bookmarklet
|
||||||
|
* Checks localStorage for BMO GAM authentication keys (bmo.gam.auth.consumerKey and bmo.gam.auth.consumerSecret).
|
||||||
|
* If they don't exist, modifies the current URL to include the authentication parameters and reloads the page.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Configuration - Update these values as needed
|
||||||
|
const DEFAULT_CONSUMER_KEY = 'RR5x0svWu5GqUEmoDzFRX297b8mjszeA';
|
||||||
|
const DEFAULT_CONSUMER_SECRET = '5haGeZQUfNlHVegw';
|
||||||
|
|
||||||
|
// Check if BMO GAM auth keys exist in localStorage
|
||||||
|
const consumerKey = localStorage.getItem('bmo.gam.auth.consumerKey');
|
||||||
|
const consumerSecret = localStorage.getItem('bmo.gam.auth.consumerSecret');
|
||||||
|
|
||||||
|
if (!consumerKey || !consumerSecret) {
|
||||||
|
// Keys don't exist, modify the URL
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
|
||||||
|
// Remove existing query parameters (everything after ?)
|
||||||
|
const baseUrl = currentUrl.split('?')[0];
|
||||||
|
|
||||||
|
// Add the authentication parameters
|
||||||
|
const newUrl = baseUrl + '?consumerKey=' + DEFAULT_CONSUMER_KEY + '&consumerSecret=' + DEFAULT_CONSUMER_SECRET;
|
||||||
|
|
||||||
|
// Reload with the new URL
|
||||||
|
window.location.href = newUrl;
|
||||||
|
} else {
|
||||||
|
// Keys exist, show confirmation
|
||||||
|
console.log('BMO GAM authentication keys found in localStorage');
|
||||||
|
alert('BMO GAM authentication keys already exist in localStorage:\n\nConsumer Key: ' + consumerKey + '\nConsumer Secret: ' + consumerSecret);
|
||||||
|
}
|
||||||
18
src/utils/bookmarklets/dag.js
Normal file
18
src/utils/bookmarklets/dag.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Opens the DAG Task details page(s) based on user input.
|
||||||
|
* If user provides a comma-separated list of DAG Task numbers, it opens each task's details page in a new tab.
|
||||||
|
* If user does not provide any input, it opens the default DAG Tasks page in a new tab.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*/
|
||||||
|
let answers = prompt("Enter the DAG Task #s, separated by commas");
|
||||||
|
const splitAnswers = answers ? answers.split(",") : false;
|
||||||
|
let url = "https://dag.tools.mdgapp.net/Tasks/Tasks.asp";
|
||||||
|
if (splitAnswers) {
|
||||||
|
splitAnswers.forEach(answer => {
|
||||||
|
let moidUrl = "https://dag.tools.mdgapp.net/Tasks/TaskDetail.asp?Cmd=Details&TaskID=" + answer.trim();
|
||||||
|
window.open(moidUrl, '_blank');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.open(url, '_blank').focus();
|
||||||
|
}
|
||||||
@@ -9,8 +9,9 @@
|
|||||||
* 4. Copies the decoded string to the clipboard.
|
* 4. Copies the decoded string to the clipboard.
|
||||||
*
|
*
|
||||||
* Note: This function uses the Clipboard API which might not be fully supported in all browsers.
|
* Note: This function uses the Clipboard API which might not be fully supported in all browsers.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
*/
|
*/
|
||||||
javascript:(function() {
|
|
||||||
let answer = prompt("Enter the HashID");
|
let answer = prompt("Enter the HashID");
|
||||||
let decodedStr = decodeURIComponent(answer);
|
let decodedStr = decodeURIComponent(answer);
|
||||||
alert(decodedStr);
|
alert(decodedStr);
|
||||||
@@ -18,4 +19,3 @@ javascript:(function() {
|
|||||||
navigator.clipboard.writeText(decodedStr)
|
navigator.clipboard.writeText(decodedStr)
|
||||||
.then(() => console.log('Decoded string copied to clipboard'))
|
.then(() => console.log('Decoded string copied to clipboard'))
|
||||||
.catch(err => console.error('Error in copying decoded string to clipboard: ', err));
|
.catch(err => console.error('Error in copying decoded string to clipboard: ', err));
|
||||||
})();
|
|
||||||
@@ -10,17 +10,16 @@
|
|||||||
* 5. Opens the URL in a new browser tab and brings focus to it.
|
* 5. Opens the URL in a new browser tab and brings focus to it.
|
||||||
*
|
*
|
||||||
* Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
|
* Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
*/
|
*/
|
||||||
javascript:(function() {
|
|
||||||
let answers = prompt("Enter the JIRA Tickets, separated by commas");
|
let answers = prompt("Enter the JIRA Tickets, separated by commas");
|
||||||
const splitAnswers = answers ? answers.split(",") : false;
|
const splitAnswers = answers ? answers.split(",") : false;
|
||||||
let url = "https://fincentric.atlassian.net/jira/software/c/projects/DIP/boards/513";
|
let url = "https://communify.atlassian.net/jira/software/c/projects/DIP/boards/444";
|
||||||
if (splitAnswers) {
|
if (splitAnswers) {
|
||||||
splitAnswers.forEach(answer => {
|
splitAnswers.forEach(answer => {
|
||||||
let moidUrl = "https://fincentric.atlassian.net/browse/" + answer.trim();
|
let moidUrl = "https://communify.atlassian.net/browse/" + answer.trim();
|
||||||
window.open(moidUrl, '_blank');
|
window.open(moidUrl, '_blank');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.open(url, '_blank').focus();
|
window.open(url, '_blank').focus();
|
||||||
}
|
}
|
||||||
})();
|
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
* 5. Opens each URL in a new browser tab and brings focus to the last opened tab.
|
* 5. Opens each URL in a new browser tab and brings focus to the last opened tab.
|
||||||
*
|
*
|
||||||
* Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
|
* Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
*/
|
*/
|
||||||
javascript:(function() {
|
|
||||||
let answers = prompt("Enter the MOID #s, separated by commas");
|
let answers = prompt("Enter the MOID #s, separated by commas");
|
||||||
const splitAnswers = answers ? answers.split(",") : false;
|
const splitAnswers = answers ? answers.split(",") : false;
|
||||||
let url = "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222";
|
let url = "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222";
|
||||||
@@ -23,4 +23,3 @@ javascript:(function() {
|
|||||||
} else {
|
} else {
|
||||||
window.open(url, '_blank').focus();
|
window.open(url, '_blank').focus();
|
||||||
}
|
}
|
||||||
})();
|
|
||||||
19
src/utils/bookmarklets/notMine/jsToMsDate.js
Normal file
19
src/utils/bookmarklets/notMine/jsToMsDate.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
function jsToMsDate(jsdate) {
|
||||||
|
const ms = Date.UTC(
|
||||||
|
jsdate.getFullYear(),
|
||||||
|
jsdate.getMonth(),
|
||||||
|
jsdate.getDate(),
|
||||||
|
jsdate.getHours(),
|
||||||
|
jsdate.getMinutes(),
|
||||||
|
jsdate.getSeconds(),
|
||||||
|
jsdate.getMilliseconds()
|
||||||
|
);
|
||||||
|
const off = jsdate.getTimezoneOffset();
|
||||||
|
return (ms - off * 60 * 1000) / 86400000 + 25569;
|
||||||
|
}
|
||||||
|
|
||||||
|
const date = prompt("Enter date");
|
||||||
|
if (date) {
|
||||||
|
const parsedDate = new Date();
|
||||||
|
alert(jsToMsDate(parsedDate));
|
||||||
|
}
|
||||||
11
src/utils/bookmarklets/notMine/msToJsDate.js
Normal file
11
src/utils/bookmarklets/notMine/msToJsDate.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
function msToJsDate(msdate) {
|
||||||
|
const jscriptDateObj = new Date((msdate - 25569) * 86400000);
|
||||||
|
const timezoneOffset = jscriptDateObj.getTimezoneOffset();
|
||||||
|
jscriptDateObj.setTime((msdate - 25569 + timezoneOffset / (60 * 24)) * 86400000);
|
||||||
|
return jscriptDateObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
const date = prompt("Enter MSDate");
|
||||||
|
if (date) {
|
||||||
|
alert(msToJsDate(date));
|
||||||
|
}
|
||||||
40
src/utils/bookmarklets/notMine/showDebugInfo.js
Normal file
40
src/utils/bookmarklets/notMine/showDebugInfo.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
function setFlag(flag, state) {
|
||||||
|
function setFlagSub(url, flag, state) {
|
||||||
|
if (!url.includes(flag)) {
|
||||||
|
url += (url.includes('?') ? '&' : '?');
|
||||||
|
url += `..${flag}..=${state}`;
|
||||||
|
} else {
|
||||||
|
const re = new RegExp(`\\.\\.${flag}\\.\\.=[^&]*`);
|
||||||
|
url = url.replace(re, `..${flag}..=${state}`);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleParameter(ad, type, val) {
|
||||||
|
type = `..${type}..`;
|
||||||
|
const regex = new RegExp(`[?|&]${type}=(on|off)&?`);
|
||||||
|
const match = ad.match(regex);
|
||||||
|
if (match) {
|
||||||
|
ad = ad.replace(`${type}=${match[1]}`, `${type}=${val || (match[1] === 'on' ? 'off' : 'on')}`);
|
||||||
|
} else {
|
||||||
|
ad += (ad.includes('?') ? '&' : '?') + `${type}=${val || 'on'}`;
|
||||||
|
}
|
||||||
|
return ad;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dependencies = {
|
||||||
|
debugchartsrv: ['showdebuginfo'],
|
||||||
|
scriptscachedebug: ['scriptscache']
|
||||||
|
};
|
||||||
|
|
||||||
|
let url = window.location.href.replace(/#.*/, '');
|
||||||
|
if (dependencies[flag] && state !== 'off') {
|
||||||
|
for (const dependency of dependencies[flag]) {
|
||||||
|
url = toggleParameter(url, dependency, 'on');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url = toggleParameter(url, flag, state || null);
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFlag('showdebuginfo');
|
||||||
0
src/utils/bookmarklets/openNomad
Normal file
0
src/utils/bookmarklets/openNomad
Normal file
926
src/utils/bookmarklets/rbc-di-featureflags.js
Normal file
926
src/utils/bookmarklets/rbc-di-featureflags.js
Normal file
@@ -0,0 +1,926 @@
|
|||||||
|
/**
|
||||||
|
* This function creates a modal dialog that allows the user to toggle feature flags.
|
||||||
|
* It retrieves the feature flags from the session storage, creates checkboxes for each flag,
|
||||||
|
* and saves the updated flags back to the session storage when the user clicks the save button.
|
||||||
|
* The modal dialog is appended to the document body and can be closed by clicking the save button.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Check if modal is already open to prevent duplicates
|
||||||
|
if (document.querySelector('.rbc-feature-flags-modal')) {
|
||||||
|
console.log('Feature Flags Manager is already open');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = sessionStorage.getItem('rbc_di_session');
|
||||||
|
let parsedData;
|
||||||
|
let features;
|
||||||
|
|
||||||
|
// Handle missing or invalid rbc_di_session data
|
||||||
|
try {
|
||||||
|
if (!data) {
|
||||||
|
// Create default structure if no data exists
|
||||||
|
parsedData = {
|
||||||
|
"features": {}
|
||||||
|
};
|
||||||
|
sessionStorage.setItem('rbc_di_session', JSON.stringify(parsedData));
|
||||||
|
features = {};
|
||||||
|
} else {
|
||||||
|
parsedData = JSON.parse(data);
|
||||||
|
// Ensure features object exists
|
||||||
|
if (!parsedData.features || typeof parsedData.features !== 'object') {
|
||||||
|
parsedData.features = {};
|
||||||
|
}
|
||||||
|
features = parsedData.features;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Handle invalid JSON or other parsing errors
|
||||||
|
console.warn('Invalid rbc_di_session data, creating new structure:', error);
|
||||||
|
parsedData = {
|
||||||
|
"features": {}
|
||||||
|
};
|
||||||
|
sessionStorage.setItem('rbc_di_session', JSON.stringify(parsedData));
|
||||||
|
features = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
let modal = document.createElement('div');
|
||||||
|
modal.className = 'rbc-feature-flags-modal';
|
||||||
|
modal.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 9999;
|
||||||
|
width: min(90vw, 1200px);
|
||||||
|
max-width: 95vw;
|
||||||
|
max-height: min(90vh, 800px);
|
||||||
|
overflow-y: auto;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
font-size: clamp(12px, 2.5vw, 14px);
|
||||||
|
line-height: 1.5;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Add modal header
|
||||||
|
let modalHeader = document.createElement('div');
|
||||||
|
modalHeader.style.cssText = `
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
padding: clamp(12px, 3vw, 24px);
|
||||||
|
border-bottom: 1px solid #e6e6e6;
|
||||||
|
background-color: #ffffff;
|
||||||
|
z-index: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let headerTitle = document.createElement('h1');
|
||||||
|
headerTitle.innerText = 'Feature Flags Manager';
|
||||||
|
headerTitle.style.cssText = `
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
font-size: clamp(18px, 4vw, 24px);
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.3;
|
||||||
|
padding-right: 40px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Header close button
|
||||||
|
let headerCloseButton = document.createElement('button');
|
||||||
|
headerCloseButton.innerHTML = '×';
|
||||||
|
headerCloseButton.style.cssText = `
|
||||||
|
position: absolute;
|
||||||
|
top: 16px;
|
||||||
|
right: 16px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #666666;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
z-index: 2;
|
||||||
|
`;
|
||||||
|
|
||||||
|
headerCloseButton.addEventListener('mouseenter', function () {
|
||||||
|
this.style.backgroundColor = '#f5f5f5';
|
||||||
|
this.style.color = '#333333';
|
||||||
|
});
|
||||||
|
|
||||||
|
headerCloseButton.addEventListener('mouseleave', function () {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.color = '#666666';
|
||||||
|
});
|
||||||
|
|
||||||
|
headerCloseButton.addEventListener('click', function () {
|
||||||
|
if (modal && modal.parentNode) {
|
||||||
|
modal.parentNode.removeChild(modal);
|
||||||
|
}
|
||||||
|
if (overlay && overlay.parentNode) {
|
||||||
|
overlay.parentNode.removeChild(overlay);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
modalHeader.appendChild(headerTitle);
|
||||||
|
modalHeader.appendChild(headerCloseButton);
|
||||||
|
modal.appendChild(modalHeader);
|
||||||
|
|
||||||
|
// Container for new features (moved to top)
|
||||||
|
let newFeaturesSection = document.createElement('div');
|
||||||
|
newFeaturesSection.className = 'rbc-modal-padding';
|
||||||
|
newFeaturesSection.style.cssText = `
|
||||||
|
padding: 0 24px 24px 24px;
|
||||||
|
border-bottom: 1px solid #e6e6e6;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let newFeatureTitle = document.createElement('h3');
|
||||||
|
newFeatureTitle.innerText = 'Add New Feature Flags';
|
||||||
|
newFeatureTitle.style.cssText = `
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
`;
|
||||||
|
newFeaturesSection.appendChild(newFeatureTitle);
|
||||||
|
|
||||||
|
// Two-column container for inputs and suggestions
|
||||||
|
let twoColumnContainer = document.createElement('div');
|
||||||
|
twoColumnContainer.className = 'rbc-two-column-container';
|
||||||
|
twoColumnContainer.style.cssText = `
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 24px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Left column - Container for all new feature inputs
|
||||||
|
let leftColumn = document.createElement('div');
|
||||||
|
let newFeaturesContainer = document.createElement('div');
|
||||||
|
newFeaturesContainer.id = 'newFeaturesContainer';
|
||||||
|
leftColumn.appendChild(newFeaturesContainer);
|
||||||
|
|
||||||
|
// Flag to prevent rapid row creation
|
||||||
|
let isCreatingRow = false;
|
||||||
|
|
||||||
|
// Function to create a new feature input row
|
||||||
|
function createNewFeatureRow() {
|
||||||
|
// Prevent rapid successive row creation
|
||||||
|
if (isCreatingRow) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
isCreatingRow = true;
|
||||||
|
|
||||||
|
// Reset the flag after a short delay
|
||||||
|
setTimeout(function () {
|
||||||
|
isCreatingRow = false;
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
let newFeatureContainer = document.createElement('div');
|
||||||
|
newFeatureContainer.className = 'new-feature-row rbc-feature-row';
|
||||||
|
newFeatureContainer.style.cssText = `
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let newFeatureCheckbox = document.createElement('input');
|
||||||
|
newFeatureCheckbox.type = 'checkbox';
|
||||||
|
newFeatureCheckbox.checked = true;
|
||||||
|
newFeatureCheckbox.className = 'new-feature-checkbox';
|
||||||
|
newFeatureCheckbox.style.cssText = `
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
accent-color: #006ac3;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let newFeatureInput = document.createElement('input');
|
||||||
|
newFeatureInput.type = 'text';
|
||||||
|
newFeatureInput.placeholder = 'Enter feature flag name...';
|
||||||
|
newFeatureInput.className = 'new-feature-input rbc-feature-input';
|
||||||
|
newFeatureInput.style.cssText = `
|
||||||
|
flex: 1;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
newFeatureInput.addEventListener('focus', function () {
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
this.style.outline = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
newFeatureInput.addEventListener('blur', function () {
|
||||||
|
this.style.borderColor = '#d1d5db';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update suggestions when input changes
|
||||||
|
newFeatureInput.addEventListener('input', function () {
|
||||||
|
updateSuggestionStates();
|
||||||
|
});
|
||||||
|
|
||||||
|
newFeatureInput.addEventListener('keydown', handleNewFeatureInputKeydown); // Attach keydown listener
|
||||||
|
// Remove row on backspace if input is empty - cross-browser compatible
|
||||||
|
newFeatureInput.addEventListener('keydown', function (e) {
|
||||||
|
var key = e.key || e.keyCode;
|
||||||
|
var isBackspace = key === 'Backspace' || key === 8;
|
||||||
|
if (isBackspace && this.value === '') {
|
||||||
|
var parentRow = this.closest ? this.closest('.new-feature-row') : this.parentNode.parentNode;
|
||||||
|
if (parentRow && newFeaturesContainer.children.length > 1) {
|
||||||
|
parentRow.remove ? parentRow.remove() : parentRow.parentNode.removeChild(parentRow);
|
||||||
|
// Update suggestions after removing a row
|
||||||
|
updateSuggestionStates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let removeButton = document.createElement('button');
|
||||||
|
removeButton.innerText = 'Remove';
|
||||||
|
removeButton.style.cssText = `
|
||||||
|
padding: 6px 12px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #666666;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
removeButton.addEventListener('mouseenter', function () {
|
||||||
|
this.style.backgroundColor = '#ffebee';
|
||||||
|
this.style.borderColor = '#d32f2f';
|
||||||
|
this.style.color = '#d32f2f';
|
||||||
|
});
|
||||||
|
|
||||||
|
removeButton.addEventListener('mouseleave', function () {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.borderColor = '#d1d5db';
|
||||||
|
this.style.color = '#666666';
|
||||||
|
});
|
||||||
|
|
||||||
|
removeButton.addEventListener('click', function () {
|
||||||
|
if (newFeatureContainer.remove) {
|
||||||
|
newFeatureContainer.remove();
|
||||||
|
} else {
|
||||||
|
newFeatureContainer.parentNode.removeChild(newFeatureContainer);
|
||||||
|
}
|
||||||
|
// Update suggestions after removing a row
|
||||||
|
updateSuggestionStates();
|
||||||
|
});
|
||||||
|
|
||||||
|
newFeatureContainer.appendChild(newFeatureCheckbox);
|
||||||
|
newFeatureContainer.appendChild(newFeatureInput);
|
||||||
|
newFeatureContainer.appendChild(removeButton);
|
||||||
|
|
||||||
|
return newFeatureContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add initial new feature row
|
||||||
|
newFeaturesContainer.appendChild(createNewFeatureRow());
|
||||||
|
|
||||||
|
// Add button to add more feature rows
|
||||||
|
let addFeatureButton = document.createElement('button');
|
||||||
|
addFeatureButton.innerText = '+ Add Another Feature Flag';
|
||||||
|
addFeatureButton.style.cssText = `
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #006ac3;
|
||||||
|
border: 1px solid #006ac3;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 8px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
addFeatureButton.addEventListener('mouseenter', function () {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
});
|
||||||
|
|
||||||
|
addFeatureButton.addEventListener('mouseleave', function () {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
});
|
||||||
|
|
||||||
|
addFeatureButton.addEventListener('click', function () {
|
||||||
|
var newRow = createNewFeatureRow();
|
||||||
|
if (newRow) {
|
||||||
|
newFeaturesContainer.appendChild(newRow);
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
leftColumn.appendChild(addFeatureButton);
|
||||||
|
|
||||||
|
// Right column - Create suggestions column
|
||||||
|
let suggestionsColumn = document.createElement('div');
|
||||||
|
suggestionsColumn.style.cssText = `
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 200px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let suggestionsTitle = document.createElement('h3');
|
||||||
|
suggestionsTitle.innerText = 'Suggestions';
|
||||||
|
suggestionsTitle.style.cssText = `
|
||||||
|
margin: 0 0 12px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
`;
|
||||||
|
suggestionsColumn.appendChild(suggestionsTitle);
|
||||||
|
|
||||||
|
let suggestionsList = document.createElement('div');
|
||||||
|
suggestionsList.id = 'suggestionsList';
|
||||||
|
suggestionsColumn.appendChild(suggestionsList);
|
||||||
|
|
||||||
|
// Add columns to two-column container
|
||||||
|
twoColumnContainer.appendChild(leftColumn);
|
||||||
|
twoColumnContainer.appendChild(suggestionsColumn);
|
||||||
|
|
||||||
|
// Add two-column container to the section
|
||||||
|
newFeaturesSection.appendChild(twoColumnContainer);
|
||||||
|
modal.appendChild(newFeaturesSection);
|
||||||
|
|
||||||
|
// Load suggestions from local storage
|
||||||
|
let savedFlags = JSON.parse(localStorage.getItem('savedFeatureFlags') || '[]');
|
||||||
|
|
||||||
|
// Initialize suggestions section with predefined feature flags
|
||||||
|
let initialSuggestions = [
|
||||||
|
'marketsResearchWebComponent',
|
||||||
|
'rcSectorAndEvents',
|
||||||
|
'rcMarketmovers',
|
||||||
|
'rcBreakingNews',
|
||||||
|
'rcReportsAndCommentary',
|
||||||
|
'optionsStrikePriceExperience',
|
||||||
|
'useRbcXrefForUs',
|
||||||
|
'sentryLogging'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Merge initial suggestions with saved flags
|
||||||
|
savedFlags = [...new Set([...savedFlags, ...initialSuggestions])];
|
||||||
|
localStorage.setItem('savedFeatureFlags', JSON.stringify(savedFlags));
|
||||||
|
|
||||||
|
// Function to check if a flag is already in use (existing features or current inputs)
|
||||||
|
function isFlagInUse(flagValue) {
|
||||||
|
// Check if it exists in the features object
|
||||||
|
if (Object.keys(features).indexOf(flagValue) !== -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's in any of the current input fields
|
||||||
|
var currentInputs = newFeaturesContainer.querySelectorAll('.new-feature-input');
|
||||||
|
for (var i = 0; i < currentInputs.length; i++) {
|
||||||
|
if (currentInputs[i].value.trim() === flagValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update suggestion states
|
||||||
|
function updateSuggestionStates() {
|
||||||
|
var suggestions = suggestionsList.querySelectorAll('.rbc-suggestion-item');
|
||||||
|
for (var i = 0; i < suggestions.length; i++) {
|
||||||
|
var suggestion = suggestions[i];
|
||||||
|
var flagValue = suggestion.innerText;
|
||||||
|
var isInUse = isFlagInUse(flagValue);
|
||||||
|
|
||||||
|
if (isInUse) {
|
||||||
|
suggestion.disabled = true;
|
||||||
|
suggestion.style.color = '#999999';
|
||||||
|
suggestion.style.borderColor = '#cccccc';
|
||||||
|
suggestion.style.cursor = 'not-allowed';
|
||||||
|
suggestion.style.opacity = '0.6';
|
||||||
|
} else {
|
||||||
|
suggestion.disabled = false;
|
||||||
|
suggestion.style.color = '#006ac3';
|
||||||
|
suggestion.style.borderColor = '#006ac3';
|
||||||
|
suggestion.style.cursor = 'pointer';
|
||||||
|
suggestion.style.opacity = '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate suggestions list - cross-browser compatible
|
||||||
|
for (var k = 0; k < savedFlags.length; k++) {
|
||||||
|
var flag = savedFlags[k];
|
||||||
|
var suggestionItem = document.createElement('button');
|
||||||
|
suggestionItem.className = 'rbc-suggestion-item';
|
||||||
|
suggestionItem.innerText = flag;
|
||||||
|
var isInUse = isFlagInUse(flag);
|
||||||
|
suggestionItem.style.cssText =
|
||||||
|
'padding: 6px 12px;' +
|
||||||
|
'margin-bottom: 6px;' +
|
||||||
|
'margin-right: 6px;' +
|
||||||
|
'background-color: transparent;' +
|
||||||
|
'color: ' + (isInUse ? '#999999' : '#006ac3') + ';' +
|
||||||
|
'border: 1px solid ' + (isInUse ? '#cccccc' : '#006ac3') + ';' +
|
||||||
|
'border-radius: 4px;' +
|
||||||
|
'font-size: 12px;' +
|
||||||
|
'cursor: ' + (isInUse ? 'not-allowed' : 'pointer') + ';' +
|
||||||
|
'transition: all 0.2s ease;' +
|
||||||
|
'display: inline-block;' +
|
||||||
|
'width: 100%;' +
|
||||||
|
'text-align: left;' +
|
||||||
|
(isInUse ? 'opacity: 0.6;' : '');
|
||||||
|
|
||||||
|
if (isInUse) {
|
||||||
|
suggestionItem.disabled = true;
|
||||||
|
} else {
|
||||||
|
suggestionItem.addEventListener('mouseenter', function () {
|
||||||
|
if (!this.disabled) {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
suggestionItem.addEventListener('mouseleave', function () {
|
||||||
|
if (!this.disabled) {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Use closure to capture the flag value
|
||||||
|
(function (flagValue) {
|
||||||
|
suggestionItem.addEventListener('click', function () {
|
||||||
|
if (this.disabled) return; // Don't proceed if disabled
|
||||||
|
|
||||||
|
// Check if there's an empty input to fill first
|
||||||
|
var existingInputs = newFeaturesContainer.querySelectorAll('.new-feature-input');
|
||||||
|
var emptyInput = null;
|
||||||
|
|
||||||
|
for (var i = 0; i < existingInputs.length; i++) {
|
||||||
|
if (!existingInputs[i].value.trim()) {
|
||||||
|
emptyInput = existingInputs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emptyInput) {
|
||||||
|
// Fill the empty input and focus it
|
||||||
|
emptyInput.value = flagValue;
|
||||||
|
emptyInput.focus();
|
||||||
|
// Only create a new empty row if this was the last empty input
|
||||||
|
var hasOtherEmptyInputs = false;
|
||||||
|
for (var j = 0; j < existingInputs.length; j++) {
|
||||||
|
if (existingInputs[j] !== emptyInput && !existingInputs[j].value.trim()) {
|
||||||
|
hasOtherEmptyInputs = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasOtherEmptyInputs) {
|
||||||
|
var newRow = createNewFeatureRow();
|
||||||
|
if (newRow) {
|
||||||
|
newFeaturesContainer.appendChild(newRow);
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No empty input found, create a new row with the suggestion
|
||||||
|
var newRow = createNewFeatureRow();
|
||||||
|
if (newRow) {
|
||||||
|
newRow.querySelector('.new-feature-input').value = flagValue;
|
||||||
|
newFeaturesContainer.appendChild(newRow);
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update suggestion states after adding the flag
|
||||||
|
updateSuggestionStates();
|
||||||
|
});
|
||||||
|
})(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
suggestionsList.appendChild(suggestionItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial update of suggestion states
|
||||||
|
updateSuggestionStates();
|
||||||
|
|
||||||
|
// Save new feature flags to local storage
|
||||||
|
function saveFeatureFlagToLocalStorage(flag) {
|
||||||
|
if (!savedFlags.includes(flag)) {
|
||||||
|
savedFlags.push(flag);
|
||||||
|
localStorage.setItem('savedFeatureFlags', JSON.stringify(savedFlags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define saveButton earlier in the code
|
||||||
|
let saveButton = document.createElement('button');
|
||||||
|
saveButton.innerText = 'Save Changes';
|
||||||
|
saveButton.style.cssText = `
|
||||||
|
padding: 12px 24px;
|
||||||
|
background-color: #006ac3;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 2px solid #006ac3;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
saveButton.addEventListener('mouseenter', function () {
|
||||||
|
this.style.backgroundColor = '#0051a5';
|
||||||
|
this.style.borderColor = '#0051a5';
|
||||||
|
});
|
||||||
|
|
||||||
|
saveButton.addEventListener('mouseleave', function () {
|
||||||
|
this.style.backgroundColor = '#006ac3';
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update save button to store new flags in local storage - cross-browser compatible
|
||||||
|
saveButton.addEventListener('click', function () {
|
||||||
|
var checkboxes = modal.querySelectorAll('input[type="checkbox"]:not(.new-feature-checkbox)');
|
||||||
|
for (var i = 0; i < checkboxes.length; i++) {
|
||||||
|
var checkbox = checkboxes[i];
|
||||||
|
features[checkbox.id] = checkbox.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process all new feature inputs
|
||||||
|
var newFeatureRows = modal.querySelectorAll('.new-feature-row');
|
||||||
|
for (var j = 0; j < newFeatureRows.length; j++) {
|
||||||
|
var row = newFeatureRows[j];
|
||||||
|
var input = row.querySelector('.new-feature-input');
|
||||||
|
var checkbox = row.querySelector('.new-feature-checkbox');
|
||||||
|
if (input.value && input.value.trim() !== '') {
|
||||||
|
features[input.value] = checkbox.checked;
|
||||||
|
saveFeatureFlagToLocalStorage(input.value.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedData.features = features;
|
||||||
|
|
||||||
|
sessionStorage.setItem('rbc_di_session', JSON.stringify(parsedData));
|
||||||
|
|
||||||
|
// Only remove modal/overlay if they exist in the DOM
|
||||||
|
if (modal && modal.parentNode) modal.parentNode.removeChild(modal);
|
||||||
|
if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Action buttons container
|
||||||
|
let actionButtons = document.createElement('div');
|
||||||
|
actionButtons.className = 'rbc-action-buttons';
|
||||||
|
actionButtons.style.cssText = `
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 24px;
|
||||||
|
border-top: 1px solid #e6e6e6;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-radius: 0 0 8px 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Append actionButtons to the modal later in the code
|
||||||
|
modal.appendChild(actionButtons);
|
||||||
|
|
||||||
|
// Append saveButton to actionButtons after its definition
|
||||||
|
actionButtons.appendChild(saveButton);
|
||||||
|
|
||||||
|
// Existing Features Section
|
||||||
|
let existingFeaturesHeader = document.createElement('h3');
|
||||||
|
existingFeaturesHeader.innerText = 'Existing Feature Flags';
|
||||||
|
existingFeaturesHeader.style.cssText = `
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
padding: 0 24px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
`;
|
||||||
|
modal.appendChild(existingFeaturesHeader);
|
||||||
|
|
||||||
|
// Main content container for existing features
|
||||||
|
let modalContent = document.createElement('div');
|
||||||
|
modalContent.className = 'rbc-existing-features-grid';
|
||||||
|
modalContent.style.cssText = `
|
||||||
|
padding: 0 24px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: calc(100vh - 400px);
|
||||||
|
`;
|
||||||
|
|
||||||
|
for (let key in features) {
|
||||||
|
if (features.hasOwnProperty(key) && typeof features[key] === 'boolean') {
|
||||||
|
let checkboxContainer = document.createElement('div');
|
||||||
|
checkboxContainer.style.cssText = `
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
checkboxContainer.addEventListener('mouseenter', function () {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
});
|
||||||
|
|
||||||
|
checkboxContainer.addEventListener('mouseleave', function () {
|
||||||
|
this.style.backgroundColor = '#fafafa';
|
||||||
|
this.style.borderColor = '#e6e6e6';
|
||||||
|
});
|
||||||
|
|
||||||
|
let checkbox = document.createElement('input');
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.id = key;
|
||||||
|
checkbox.checked = features[key];
|
||||||
|
checkbox.style.cssText = `
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
accent-color: #006ac3;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let label = document.createElement('label');
|
||||||
|
label.htmlFor = key;
|
||||||
|
label.innerText = key;
|
||||||
|
label.style.cssText = `
|
||||||
|
flex: 1;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #333333;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let deleteButton = document.createElement('button');
|
||||||
|
deleteButton.innerHTML = '×';
|
||||||
|
deleteButton.style.cssText = `
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 18px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
deleteButton.addEventListener('mouseenter', function () {
|
||||||
|
this.style.backgroundColor = '#ffebee';
|
||||||
|
this.style.color = '#d32f2f';
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteButton.addEventListener('mouseleave', function () {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.color = '#666666';
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteButton.addEventListener('click', function () {
|
||||||
|
delete features[key];
|
||||||
|
if (checkboxContainer.remove) {
|
||||||
|
checkboxContainer.remove();
|
||||||
|
} else {
|
||||||
|
checkboxContainer.parentNode.removeChild(checkboxContainer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
checkboxContainer.appendChild(checkbox);
|
||||||
|
checkboxContainer.appendChild(label);
|
||||||
|
checkboxContainer.appendChild(deleteButton);
|
||||||
|
modalContent.appendChild(checkboxContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modal.appendChild(modalContent);
|
||||||
|
|
||||||
|
let cancelButton = document.createElement('button');
|
||||||
|
cancelButton.innerText = 'Cancel';
|
||||||
|
cancelButton.style.cssText = `
|
||||||
|
padding: 12px 24px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #006ac3;
|
||||||
|
border: 2px solid #006ac3;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
`;
|
||||||
|
|
||||||
|
cancelButton.addEventListener('mouseenter', function () {
|
||||||
|
this.style.backgroundColor = '#f3f7f8';
|
||||||
|
this.style.borderColor = '#0051a5';
|
||||||
|
this.style.color = '#0051a5';
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.addEventListener('mouseleave', function () {
|
||||||
|
this.style.backgroundColor = 'transparent';
|
||||||
|
this.style.borderColor = '#006ac3';
|
||||||
|
this.style.color = '#006ac3';
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.addEventListener('click', function () {
|
||||||
|
if (modal && modal.parentNode) {
|
||||||
|
modal.parentNode.removeChild(modal);
|
||||||
|
}
|
||||||
|
if (overlay && overlay.parentNode) {
|
||||||
|
overlay.parentNode.removeChild(overlay);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
actionButtons.appendChild(cancelButton);
|
||||||
|
actionButtons.appendChild(saveButton);
|
||||||
|
|
||||||
|
modal.appendChild(actionButtons);
|
||||||
|
|
||||||
|
let overlay = document.createElement('div');
|
||||||
|
overlay.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 9998;
|
||||||
|
-webkit-backdrop-filter: blur(2px);
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
|
// Close modal on Escape key - cross-browser compatible
|
||||||
|
function closeFeatureFlagsModal() {
|
||||||
|
if (modal && modal.parentNode) {
|
||||||
|
modal.parentNode.removeChild(modal);
|
||||||
|
}
|
||||||
|
if (overlay && overlay.parentNode) {
|
||||||
|
overlay.parentNode.removeChild(overlay);
|
||||||
|
}
|
||||||
|
document.removeEventListener('keydown', escListener);
|
||||||
|
}
|
||||||
|
function escListener(e) {
|
||||||
|
var key = e.key || e.keyCode;
|
||||||
|
if (key === 'Escape' || key === 27) closeFeatureFlagsModal();
|
||||||
|
}
|
||||||
|
document.addEventListener('keydown', escListener);
|
||||||
|
|
||||||
|
// Update Enter key behavior to create only one new feature flag input - cross-browser compatible
|
||||||
|
function handleNewFeatureInputKeydown(e) {
|
||||||
|
var key = e.key || e.keyCode;
|
||||||
|
var isEnter = key === 'Enter' || key === 13;
|
||||||
|
var isCtrlPressed = e.ctrlKey || e.metaKey; // metaKey for Mac compatibility
|
||||||
|
|
||||||
|
if (isEnter && !isCtrlPressed) {
|
||||||
|
// Add a single new feature flag row
|
||||||
|
e.preventDefault();
|
||||||
|
var lastInput = newFeaturesContainer.querySelector('.new-feature-row:last-child .new-feature-input');
|
||||||
|
if (!lastInput || !lastInput.value.trim()) {
|
||||||
|
return; // Prevent adding a new row if the last input is empty
|
||||||
|
}
|
||||||
|
var newRow = createNewFeatureRow();
|
||||||
|
if (newRow) {
|
||||||
|
newFeaturesContainer.appendChild(newRow);
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
}
|
||||||
|
} else if (isEnter && isCtrlPressed) {
|
||||||
|
// Trigger the Save Changes button
|
||||||
|
e.preventDefault();
|
||||||
|
saveButton.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the keydown listener to all new feature inputs - cross-browser compatible
|
||||||
|
function attachKeydownListenerToNewFeatureInputs() {
|
||||||
|
var newFeatureInputs = modal.querySelectorAll('.new-feature-input');
|
||||||
|
for (var i = 0; i < newFeatureInputs.length; i++) {
|
||||||
|
var input = newFeatureInputs[i];
|
||||||
|
// Remove existing listener to avoid duplicates
|
||||||
|
input.removeEventListener('keydown', handleNewFeatureInputKeydown);
|
||||||
|
input.addEventListener('keydown', handleNewFeatureInputKeydown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach listeners to initial rows
|
||||||
|
attachKeydownListenerToNewFeatureInputs();
|
||||||
|
|
||||||
|
// Remove the duplicate event listener that was causing double row creation
|
||||||
|
// The handleNewFeatureInputKeydown function already handles Enter key presses
|
||||||
|
|
||||||
|
// Add a comprehensive style block for responsive design and isolation from main website
|
||||||
|
let styleBlock = document.createElement('style');
|
||||||
|
styleBlock.innerHTML = `
|
||||||
|
/* Base styles and website isolation */
|
||||||
|
.rbc-feature-flags-modal input[type="checkbox"] + label::before {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: -25%;
|
||||||
|
background-color: transparent;
|
||||||
|
height: 26px;
|
||||||
|
width: 26px;
|
||||||
|
margin: 1px;
|
||||||
|
margin-bottom:-1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive modal styles */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.rbc-feature-flags-modal {
|
||||||
|
width: 95vw !important;
|
||||||
|
max-width: 95vw !important;
|
||||||
|
max-height: 95vh !important;
|
||||||
|
font-size: 16px !important; /* Prevent zoom on iOS */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stack columns on mobile */
|
||||||
|
.rbc-two-column-container {
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
|
gap: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust existing features grid for mobile */
|
||||||
|
.rbc-existing-features-grid {
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
|
gap: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make feature rows more mobile-friendly */
|
||||||
|
.rbc-feature-row {
|
||||||
|
flex-wrap: wrap !important;
|
||||||
|
gap: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rbc-feature-input {
|
||||||
|
min-width: 150px !important;
|
||||||
|
font-size: 16px !important; /* Prevent zoom on iOS */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust button sizes for mobile */
|
||||||
|
.rbc-action-buttons {
|
||||||
|
flex-direction: column !important;
|
||||||
|
gap: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rbc-action-buttons button {
|
||||||
|
width: 100% !important;
|
||||||
|
padding: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make suggestions more mobile-friendly */
|
||||||
|
.rbc-suggestion-item {
|
||||||
|
font-size: 14px !important;
|
||||||
|
padding: 8px 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust close button for mobile */
|
||||||
|
.rbc-close-button {
|
||||||
|
top: 8px !important;
|
||||||
|
right: 8px !important;
|
||||||
|
width: 40px !important;
|
||||||
|
height: 40px !important;
|
||||||
|
font-size: 20px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.rbc-feature-flags-modal {
|
||||||
|
width: 98vw !important;
|
||||||
|
max-height: 98vh !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rbc-modal-padding {
|
||||||
|
padding: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rbc-feature-input {
|
||||||
|
min-width: 120px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Landscape mobile adjustments */
|
||||||
|
@media (max-width: 768px) and (orientation: landscape) {
|
||||||
|
.rbc-feature-flags-modal {
|
||||||
|
max-height: 90vh !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Append the style block to the modal
|
||||||
|
modal.appendChild(styleBlock);
|
||||||
89
src/utils/bookmarklets/rbc-di-featureflags.md
Normal file
89
src/utils/bookmarklets/rbc-di-featureflags.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Feature Flags Modal – RBC Style
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This modal allows users to view, add, toggle, and remove feature flags stored in session storage. It is styled to match the RBC Direct Investing modal design, with a professional, modern look and clear sectioning.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🆕 New Layout (as of July 2025)
|
||||||
|
|
||||||
|
### 1. **Header**
|
||||||
|
- **Title:** `Feature Flags Manager`
|
||||||
|
- Large, bold, and visually separated from the rest of the modal.
|
||||||
|
|
||||||
|
### 2. **Add New Feature Flags (Top Section)**
|
||||||
|
- **Header:** `Add New Feature Flags`
|
||||||
|
- Always at the top, right below the main title.
|
||||||
|
- Allows adding multiple new feature flags before saving.
|
||||||
|
- Each new flag row includes:
|
||||||
|
- Checkbox (default: checked)
|
||||||
|
- Text input for flag name
|
||||||
|
- Remove button
|
||||||
|
- "+ Add Another Feature Flag" button for more rows
|
||||||
|
- Section is visually separated with a border below.
|
||||||
|
|
||||||
|
### 3. **Existing Feature Flags**
|
||||||
|
- **Header:** `Existing Feature Flags`
|
||||||
|
- Appears below the new flags section.
|
||||||
|
- Flags are displayed in a two-column grid.
|
||||||
|
- Each flag is shown as a card with:
|
||||||
|
- Checkbox (toggle on/off)
|
||||||
|
- Flag name
|
||||||
|
- Delete (×) button
|
||||||
|
- Cards have hover and focus effects for clarity.
|
||||||
|
|
||||||
|
### 4. **Action Buttons (Footer)**
|
||||||
|
- **Buttons:** `Cancel` (secondary), `Save Changes` (primary)
|
||||||
|
- Right-aligned, styled to match RBC's button system
|
||||||
|
- Cancel closes the modal without saving
|
||||||
|
- Save applies all changes and reloads the page
|
||||||
|
|
||||||
|
### 5. **Close Button**
|
||||||
|
- Top-right corner (×), styled as a circular icon
|
||||||
|
- Closes the modal and overlay
|
||||||
|
|
||||||
|
### 6. **Overlay**
|
||||||
|
- Dimmed, blurred background overlay for focus
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Styling Details
|
||||||
|
- **Colors:** RBC blue (`#006ac3`), hover blue (`#0051a5`), error red (`#d32f2f`), backgrounds (`#fafafa`, `#f3f7f8`)
|
||||||
|
- **Typography:** System font stack, clear hierarchy
|
||||||
|
- **Spacing:** Generous padding, grid layout, rounded corners
|
||||||
|
- **Accessibility:** High contrast, focus states, large click targets
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Usage
|
||||||
|
- The modal is generated and injected by the `rbc-di-featureflags.js` bookmarklet.
|
||||||
|
- All changes are saved to `sessionStorage` under the `rbc_di_session` key.
|
||||||
|
- Use the provided script to generate a bookmarklet for browser use.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Example Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ Feature Flags Manager │ ← Main Header
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ Add New Feature Flags │ ← New section (top)
|
||||||
|
│ [+] Add Another Feature Flag │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ Existing Feature Flags │ ← New header
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ Flag 1 [×] │ │ Flag 2 [×] │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ [Cancel] [Save Changes] │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Improvements Over Previous Version
|
||||||
|
- New flags section is always visible and prioritized
|
||||||
|
- Existing flags are clearly separated and labeled
|
||||||
|
- Modern, accessible, and brand-consistent design
|
||||||
|
- All actions (add, remove, toggle, save, cancel) are visually clear and easy to use
|
||||||
23
src/utils/bookmarklets/rbcSessionStorage.js
Normal file
23
src/utils/bookmarklets/rbcSessionStorage.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the 'fnc-rbc-session' property from the session storage if it exists.
|
||||||
|
* If the property exists, it prompts the user for confirmation before deleting.
|
||||||
|
* If the property does not exist, it displays an alert message.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*/
|
||||||
|
const rbcSession = sessionStorage.getItem('fnc-rbc-session');
|
||||||
|
if (rbcSession) {
|
||||||
|
const sessionValue = JSON.parse(rbcSession);
|
||||||
|
let properties = '';
|
||||||
|
for (const key in sessionValue) {
|
||||||
|
properties += `${key}: ${sessionValue[key]}\n`;
|
||||||
|
}
|
||||||
|
const confirmDelete = confirm(`The properties in 'fnc-rbc-session' are:\n\n${properties}\nDo you want to delete 'fnc-rbc-session'?`);
|
||||||
|
if (confirmDelete) {
|
||||||
|
sessionStorage.removeItem('fnc-rbc-session');
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("'fnc-rbc-session' does not exist in session storage.");
|
||||||
|
}
|
||||||
29
src/utils/bookmarklets/rbcSiteNavigator.js
Normal file
29
src/utils/bookmarklets/rbcSiteNavigator.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a specific URL based on the provided environment and language.
|
||||||
|
* Prompts the user to enter the environment and language in the format 'prod|ste,en|fr'.
|
||||||
|
* If the input is valid, it opens the corresponding URL in a new tab.
|
||||||
|
* If the input is invalid, it logs an error message to the console.
|
||||||
|
*
|
||||||
|
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*/
|
||||||
|
const answer = prompt("Please enter the env and language in the format 'prod|ste,en|fr':");
|
||||||
|
const [env, language] = answer.split(/,|\s/);
|
||||||
|
switch (env) {
|
||||||
|
case "prod":
|
||||||
|
if (language === "fr") {
|
||||||
|
window.open("https://www1.royalbank.com/french/netaction/sgnf.html", "_blank").focus();
|
||||||
|
} else {
|
||||||
|
window.open("https://www1.royalbank.com/english/netaction/sgne.html", "_blank").focus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ste":
|
||||||
|
if (language === "fr") {
|
||||||
|
window.open("https://www1.steroyalbank.com/french/netaction/sgnf.html", "_blank").focus();
|
||||||
|
} else {
|
||||||
|
window.open("https://www1.steroyalbank.com/english/netaction/sgne.html", "_blank").focus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("Invalid input");
|
||||||
|
}
|
||||||
48
src/utils/bookmarklets/rbcWatchlistPopulator.js
Normal file
48
src/utils/bookmarklets/rbcWatchlistPopulator.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
This code is a bookmarklet that populates a watchlist on a web page.
|
||||||
|
It defines an array of new securities and a function called populateWatchlist.
|
||||||
|
The function finds the input field on the page, iterates over the new securities array,
|
||||||
|
and sets the value of the input field to each security in the array.
|
||||||
|
It then triggers events to simulate user input and key presses to add the security to the watchlist.
|
||||||
|
The process repeats for each security in the array with a delay of 2.5 seconds between each iteration.
|
||||||
|
The code is executed when the bookmarklet is clicked on the web page.
|
||||||
|
|
||||||
|
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
|
||||||
|
*/
|
||||||
|
const newSecurities = [
|
||||||
|
'AMX',
|
||||||
|
'VNORP',
|
||||||
|
'AMBKP',
|
||||||
|
'CSU.DB',
|
||||||
|
'NFLX',
|
||||||
|
'ICFSSUSN',
|
||||||
|
'ICRP',
|
||||||
|
'LDSVF',
|
||||||
|
'AMTPQ',
|
||||||
|
'DSHKP',
|
||||||
|
'AITRR',
|
||||||
|
'URW',
|
||||||
|
'AP.UN',
|
||||||
|
'PVF.WT'
|
||||||
|
];
|
||||||
|
function populateWatchlist() {
|
||||||
|
const foundInputs = document.querySelectorAll('.rbc-typeahead-search-input');
|
||||||
|
const input = foundInputs && foundInputs.length > 1 ? foundInputs[1] : null;
|
||||||
|
if (input) {
|
||||||
|
let index = 0;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (index >= newSecurities.length) {
|
||||||
|
clearInterval(interval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
input.value = newSecurities[index];
|
||||||
|
input.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
setTimeout(() => {
|
||||||
|
input.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 }));
|
||||||
|
}, 1000);
|
||||||
|
index++;
|
||||||
|
}, 2500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
populateWatchlist();
|
||||||
20
src/utils/bookmarklets/tokenGrabber.js
Normal file
20
src/utils/bookmarklets/tokenGrabber.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the user session token from the 'fnc-rbc-session' session storage and copies it to the clipboard.
|
||||||
|
*/
|
||||||
|
function grabToken() {
|
||||||
|
const rbcSession = sessionStorage.getItem('fnc-rbc-session');
|
||||||
|
if (rbcSession) {
|
||||||
|
const sessionValues = JSON.parse(rbcSession);
|
||||||
|
navigator.clipboard.writeText(sessionValues.token)
|
||||||
|
.then(() => {
|
||||||
|
console.log(`user session token ${sessionValues.token} copied to clipboard!`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Failed to copy session token:', error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error('fnc-rbc-session session not found!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grabToken();
|
||||||
89
src/utils/bookmarklets/workspace.js
Normal file
89
src/utils/bookmarklets/workspace.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
const urls = {
|
||||||
|
JIRAMetricsDashboard: "https://fincentric.atlassian.net/jira/dashboards/14019/",
|
||||||
|
JIRABoard: "https://fincentric.atlassian.net/jira/software/c/projects/DIP/boards/513",
|
||||||
|
MOIDDashboard: "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222",
|
||||||
|
DIUserLoginsConfluencePage: "https://confluence.ihsmarkit.com/pages/viewpage.action?spaceKey=MOD&title=DI+User+Logins#direct-investing--686175318",
|
||||||
|
WEUserAdmin: "https://intranet.tools.mdgapp.net/P/PTC1/UserAdmin"
|
||||||
|
};
|
||||||
|
|
||||||
|
let modal = document.createElement('div');
|
||||||
|
modal.style.position = 'fixed';
|
||||||
|
modal.style.top = '50%';
|
||||||
|
modal.style.left = '50%';
|
||||||
|
modal.style.transform = 'translate(-50%, -50%)';
|
||||||
|
modal.style.backgroundColor = 'white';
|
||||||
|
modal.style.padding = '20px';
|
||||||
|
modal.style.border = '1px solid black';
|
||||||
|
modal.style.zIndex = '999';
|
||||||
|
modal.style.display = 'flex';
|
||||||
|
modal.style.flexWrap = 'wrap';
|
||||||
|
|
||||||
|
Object.keys(urls).forEach(key => {
|
||||||
|
let checkboxContainer = document.createElement('div');
|
||||||
|
checkboxContainer.style.width = '50%';
|
||||||
|
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.id = key;
|
||||||
|
checkbox.name = key;
|
||||||
|
checkbox.value = urls[key];
|
||||||
|
|
||||||
|
const label = document.createElement('label');
|
||||||
|
label.htmlFor = key;
|
||||||
|
label.innerText = key.split(/(?=[A-Z][a-z])/).join(' ');
|
||||||
|
|
||||||
|
checkboxContainer.appendChild(checkbox);
|
||||||
|
checkboxContainer.appendChild(label);
|
||||||
|
modal.appendChild(checkboxContainer);
|
||||||
|
});
|
||||||
|
|
||||||
|
const startButton = document.createElement('button');
|
||||||
|
startButton.innerText = 'Start';
|
||||||
|
startButton.addEventListener('click', () => {
|
||||||
|
const selectedUrls = Array.from(modal.querySelectorAll('input[type="checkbox"]:checked')).map(checkbox => checkbox.value);
|
||||||
|
selectedUrls.forEach(url => window.open(url, '_blank'));
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
document.body.removeChild(overlay);
|
||||||
|
});
|
||||||
|
|
||||||
|
let closeButton = document.createElement('button');
|
||||||
|
closeButton.innerText = 'X';
|
||||||
|
closeButton.style.position = 'absolute';
|
||||||
|
closeButton.style.right = '10px';
|
||||||
|
closeButton.style.top = '10px';
|
||||||
|
closeButton.addEventListener('click', function() {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
document.body.removeChild(overlay);
|
||||||
|
});
|
||||||
|
|
||||||
|
let cancelButton = document.createElement('button');
|
||||||
|
cancelButton.innerText = 'Cancel';
|
||||||
|
cancelButton.addEventListener('click', function() {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
document.body.removeChild(overlay);
|
||||||
|
});
|
||||||
|
|
||||||
|
let buttonContainer = document.createElement('div');
|
||||||
|
buttonContainer.style.width = '100%';
|
||||||
|
buttonContainer.style.display = 'flex';
|
||||||
|
buttonContainer.style.justifyContent = 'center';
|
||||||
|
buttonContainer.style.marginTop = '20px';
|
||||||
|
|
||||||
|
buttonContainer.appendChild(startButton);
|
||||||
|
buttonContainer.appendChild(cancelButton);
|
||||||
|
|
||||||
|
modal.appendChild(closeButton);
|
||||||
|
modal.appendChild(buttonContainer);
|
||||||
|
|
||||||
|
let overlay = document.createElement('div');
|
||||||
|
overlay.style.position = 'fixed';
|
||||||
|
overlay.style.top = '0';
|
||||||
|
overlay.style.left = '0';
|
||||||
|
overlay.style.width = '100%';
|
||||||
|
overlay.style.height = '100%';
|
||||||
|
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
||||||
|
overlay.style.zIndex = '998';
|
||||||
|
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
BIN
src/utils/chrome-extensions/chrome-network-monitor.zip
Normal file
BIN
src/utils/chrome-extensions/chrome-network-monitor.zip
Normal file
Binary file not shown.
141
src/utils/chrome-extensions/chrome-network-monitor/README.md
Normal file
141
src/utils/chrome-extensions/chrome-network-monitor/README.md
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# Network Request Monitor - Chrome Extension
|
||||||
|
|
||||||
|
A Chrome extension that monitors network requests on web pages and alerts you when specific keywords or patterns are found in the requests.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Custom Search Items**: Define a list of keywords, API endpoints, or patterns to monitor
|
||||||
|
- **Real-time Monitoring**: Automatically captures network requests as pages load
|
||||||
|
- **Match Detection**: Highlights requests that contain your search items
|
||||||
|
- **Request Details**: Shows HTTP method, URL, timestamp, status code, and matched items
|
||||||
|
- **Request Body Preview**: Displays a preview of POST request bodies
|
||||||
|
- **Badge Counter**: Shows the number of matches on the extension icon
|
||||||
|
- **Auto-refresh**: Updates the list every 2 seconds while the popup is open
|
||||||
|
|
||||||
|
## Installation Instructions
|
||||||
|
|
||||||
|
### Method 1: Load Unpacked Extension (Development Mode)
|
||||||
|
|
||||||
|
1. **Open Chrome Extensions Page**
|
||||||
|
- Navigate to `chrome://extensions/` in your Chrome browser
|
||||||
|
- Or click the three-dot menu → More Tools → Extensions
|
||||||
|
|
||||||
|
2. **Enable Developer Mode**
|
||||||
|
- Toggle the "Developer mode" switch in the top-right corner
|
||||||
|
|
||||||
|
3. **Load the Extension**
|
||||||
|
- Click the "Load unpacked" button
|
||||||
|
- Navigate to the extension folder: `C:\memorypalace\src\utils\chrome-network-monitor`
|
||||||
|
- Click "Select Folder"
|
||||||
|
|
||||||
|
4. **Verify Installation**
|
||||||
|
- You should see the "Network Request Monitor" extension appear in your extensions list
|
||||||
|
- The extension icon should appear in your Chrome toolbar
|
||||||
|
|
||||||
|
### Method 2: Pin the Extension (Recommended)
|
||||||
|
|
||||||
|
1. Click the puzzle piece icon in the Chrome toolbar
|
||||||
|
2. Find "Network Request Monitor" in the list
|
||||||
|
3. Click the pin icon to keep it visible in your toolbar
|
||||||
|
|
||||||
|
## How to Use
|
||||||
|
|
||||||
|
### 1. Add Search Items
|
||||||
|
|
||||||
|
1. Click the extension icon in your Chrome toolbar
|
||||||
|
2. In the "Search Items" section, enter the keywords or patterns you want to monitor (one per line)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
api/users
|
||||||
|
authentication
|
||||||
|
featureFlag
|
||||||
|
rbc_di_session
|
||||||
|
consumerKey
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Click "Save Search Items"
|
||||||
|
|
||||||
|
### 2. Browse Websites
|
||||||
|
|
||||||
|
- Navigate to any website
|
||||||
|
- The extension will automatically monitor all network requests
|
||||||
|
- When a match is found, the extension badge will show the number of matches
|
||||||
|
|
||||||
|
### 3. View Matched Requests
|
||||||
|
|
||||||
|
1. Click the extension icon to open the popup
|
||||||
|
2. View all matched requests for the current tab
|
||||||
|
3. See details including:
|
||||||
|
- HTTP method (GET, POST, etc.)
|
||||||
|
- Full request URL
|
||||||
|
- Timestamp
|
||||||
|
- Status code
|
||||||
|
- Matched search items
|
||||||
|
- Request body preview (for POST requests)
|
||||||
|
|
||||||
|
### 4. Manage Matches
|
||||||
|
|
||||||
|
- **Refresh**: Click "Refresh" to manually update the list
|
||||||
|
- **Clear All**: Click "Clear All" to remove all matches for the current tab
|
||||||
|
- Matches are automatically cleared when you close the tab
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
|
||||||
|
### Files Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
chrome-network-monitor/
|
||||||
|
├── manifest.json # Extension configuration
|
||||||
|
├── background.js # Background service worker
|
||||||
|
├── popup.html # Popup UI structure
|
||||||
|
├── popup.css # Popup styles
|
||||||
|
├── popup.js # Popup logic
|
||||||
|
├── icon16.png # 16x16 icon
|
||||||
|
├── icon48.png # 48x48 icon
|
||||||
|
├── icon128.png # 128x128 icon
|
||||||
|
└── README.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Permissions
|
||||||
|
|
||||||
|
- **webRequest**: Monitor network requests
|
||||||
|
- **storage**: Save search items
|
||||||
|
- **activeTab**: Access the current tab information
|
||||||
|
- **host_permissions**: Monitor requests from all URLs
|
||||||
|
|
||||||
|
### Limitations
|
||||||
|
|
||||||
|
- Maximum 100 matched requests are stored per session
|
||||||
|
- Request body preview is limited to 500 characters
|
||||||
|
- Search is case-insensitive
|
||||||
|
- Matches are tab-specific and cleared when the tab is closed
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Extension not appearing:**
|
||||||
|
- Make sure Developer Mode is enabled
|
||||||
|
- Try reloading the extension from `chrome://extensions/`
|
||||||
|
|
||||||
|
**No matches detected:**
|
||||||
|
- Verify your search items are saved
|
||||||
|
- Check that the search terms match the actual network request URLs
|
||||||
|
- Some requests may be blocked by CORS or browser security policies
|
||||||
|
|
||||||
|
**Badge not updating:**
|
||||||
|
- Close and reopen the extension popup
|
||||||
|
- Reload the web page
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
To modify the extension:
|
||||||
|
1. Edit the files in `C:\memorypalace\src\utils\chrome-network-monitor`
|
||||||
|
2. Go to `chrome://extensions/`
|
||||||
|
3. Click the refresh icon on the extension card
|
||||||
|
4. Test your changes
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The extension stores search items using Chrome's sync storage, so they'll sync across your Chrome browsers
|
||||||
|
- Network monitoring only works on http/https pages (not on chrome:// pages)
|
||||||
|
- The extension respects Chrome's security policies and cannot monitor certain protected requests
|
||||||
132
src/utils/chrome-extensions/chrome-network-monitor/background.js
Normal file
132
src/utils/chrome-extensions/chrome-network-monitor/background.js
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
// Network Request Monitor - Background Service Worker
|
||||||
|
|
||||||
|
let monitoredRequests = [];
|
||||||
|
let searchItems = [];
|
||||||
|
let autoClearOnNavigate = false;
|
||||||
|
|
||||||
|
// Load settings from storage on startup
|
||||||
|
chrome.storage.sync.get(['searchItems', 'autoClearOnNavigate'], (result) => {
|
||||||
|
searchItems = result.searchItems || [];
|
||||||
|
autoClearOnNavigate = result.autoClearOnNavigate || false;
|
||||||
|
console.log('Loaded settings:', { searchItems, autoClearOnNavigate });
|
||||||
|
});// Listen for storage changes
|
||||||
|
chrome.storage.onChanged.addListener((changes, namespace) => {
|
||||||
|
if (namespace === 'sync') {
|
||||||
|
if (changes.searchItems) {
|
||||||
|
searchItems = changes.searchItems.newValue || [];
|
||||||
|
console.log('Search items updated:', searchItems);
|
||||||
|
}
|
||||||
|
if (changes.autoClearOnNavigate) {
|
||||||
|
autoClearOnNavigate = changes.autoClearOnNavigate.newValue || false;
|
||||||
|
console.log('Auto-clear preference updated:', autoClearOnNavigate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});// Monitor web requests
|
||||||
|
chrome.webRequest.onBeforeRequest.addListener(
|
||||||
|
(details) => {
|
||||||
|
if (searchItems.length === 0) return;
|
||||||
|
|
||||||
|
const url = details.url;
|
||||||
|
const method = details.method;
|
||||||
|
let requestBody = '';
|
||||||
|
|
||||||
|
// Get request body if available
|
||||||
|
if (details.requestBody) {
|
||||||
|
if (details.requestBody.raw) {
|
||||||
|
const decoder = new TextDecoder('utf-8');
|
||||||
|
requestBody = details.requestBody.raw.map(data => decoder.decode(data.bytes)).join('');
|
||||||
|
} else if (details.requestBody.formData) {
|
||||||
|
requestBody = JSON.stringify(details.requestBody.formData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if URL or request body contains any search items
|
||||||
|
const matches = searchItems.filter(item => {
|
||||||
|
const searchString = item.toLowerCase();
|
||||||
|
return url.toLowerCase().includes(searchString) ||
|
||||||
|
requestBody.toLowerCase().includes(searchString);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matches.length > 0) {
|
||||||
|
const matchedRequest = {
|
||||||
|
url: url,
|
||||||
|
method: method,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
tabId: details.tabId,
|
||||||
|
matches: matches,
|
||||||
|
requestBody: requestBody.substring(0, 500) // Limit body preview
|
||||||
|
};
|
||||||
|
|
||||||
|
monitoredRequests.push(matchedRequest);
|
||||||
|
|
||||||
|
// Keep only last 100 requests
|
||||||
|
if (monitoredRequests.length > 100) {
|
||||||
|
monitoredRequests.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update badge to show match count
|
||||||
|
updateBadge(details.tabId);
|
||||||
|
|
||||||
|
console.log('Match found!', matchedRequest);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ urls: ["<all_urls>"] },
|
||||||
|
["requestBody"]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Monitor response headers for additional context
|
||||||
|
chrome.webRequest.onCompleted.addListener(
|
||||||
|
(details) => {
|
||||||
|
// Find matching request and add response info
|
||||||
|
const matchedIndex = monitoredRequests.findIndex(
|
||||||
|
req => req.url === details.url && req.tabId === details.tabId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (matchedIndex !== -1) {
|
||||||
|
monitoredRequests[matchedIndex].statusCode = details.statusCode;
|
||||||
|
monitoredRequests[matchedIndex].responseHeaders = details.responseHeaders;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ urls: ["<all_urls>"] },
|
||||||
|
["responseHeaders"]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update badge with match count
|
||||||
|
function updateBadge(tabId) {
|
||||||
|
const tabMatches = monitoredRequests.filter(req => req.tabId === tabId);
|
||||||
|
const count = tabMatches.length;
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
chrome.action.setBadgeText({ text: count.toString(), tabId: tabId });
|
||||||
|
chrome.action.setBadgeBackgroundColor({ color: '#FF0000', tabId: tabId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear requests for a specific tab
|
||||||
|
chrome.tabs.onRemoved.addListener((tabId) => {
|
||||||
|
monitoredRequests = monitoredRequests.filter(req => req.tabId !== tabId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear requests on navigation if auto-clear is enabled
|
||||||
|
chrome.webNavigation.onCommitted.addListener((details) => {
|
||||||
|
if (autoClearOnNavigate && details.frameId === 0) {
|
||||||
|
// Clear requests for this tab when navigating
|
||||||
|
monitoredRequests = monitoredRequests.filter(req => req.tabId !== details.tabId);
|
||||||
|
// Clear badge
|
||||||
|
chrome.action.setBadgeText({ text: '', tabId: details.tabId });
|
||||||
|
console.log('Cleared requests for tab', details.tabId, 'on navigation');
|
||||||
|
}
|
||||||
|
});// Handle messages from popup
|
||||||
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
|
if (request.action === 'getRequests') {
|
||||||
|
const tabId = request.tabId;
|
||||||
|
const tabRequests = monitoredRequests.filter(req => req.tabId === tabId);
|
||||||
|
sendResponse({ requests: tabRequests });
|
||||||
|
} else if (request.action === 'clearRequests') {
|
||||||
|
const tabId = request.tabId;
|
||||||
|
monitoredRequests = monitoredRequests.filter(req => req.tabId !== tabId);
|
||||||
|
chrome.action.setBadgeText({ text: '', tabId: tabId });
|
||||||
|
sendResponse({ success: true });
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
BIN
src/utils/chrome-extensions/chrome-network-monitor/icon128.png
Normal file
BIN
src/utils/chrome-extensions/chrome-network-monitor/icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
src/utils/chrome-extensions/chrome-network-monitor/icon16.png
Normal file
BIN
src/utils/chrome-extensions/chrome-network-monitor/icon16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 593 B |
BIN
src/utils/chrome-extensions/chrome-network-monitor/icon48.png
Normal file
BIN
src/utils/chrome-extensions/chrome-network-monitor/icon48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "Network Request Monitor",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Monitor network requests for specific keywords and patterns",
|
||||||
|
"permissions": [
|
||||||
|
"webRequest",
|
||||||
|
"webNavigation",
|
||||||
|
"storage",
|
||||||
|
"activeTab"
|
||||||
|
],
|
||||||
|
"host_permissions": [
|
||||||
|
"<all_urls>"
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"service_worker": "background.js"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"default_popup": "popup.html",
|
||||||
|
"default_icon": {
|
||||||
|
"16": "icon16.png",
|
||||||
|
"48": "icon48.png",
|
||||||
|
"128": "icon128.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"16": "icon16.png",
|
||||||
|
"48": "icon48.png",
|
||||||
|
"128": "icon128.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
297
src/utils/chrome-extensions/chrome-network-monitor/popup.css
Normal file
297
src/utils/chrome-extensions/chrome-network-monitor/popup.css
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #333;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
width: 600px;
|
||||||
|
max-height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 16px 20px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
padding: 16px 20px;
|
||||||
|
background: white;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h2 {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: #555;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: #667eea;
|
||||||
|
color: white;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-items-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchItemsInput {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
resize: vertical;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchItemsInput:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #667eea;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #5568d3;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: #6c757d;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: #5a6268;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success {
|
||||||
|
background-color: #28a745;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background-color: #dc3545;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger:hover {
|
||||||
|
background-color: #c82333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-message {
|
||||||
|
min-height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #28a745;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auto-clear-container {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label input[type="checkbox"] {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
accent-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label:hover {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requests-list {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state {
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-item {
|
||||||
|
background: #f9f9f9;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-item:hover {
|
||||||
|
background: #f0f0f0;
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-badge {
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-GET {
|
||||||
|
background-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-POST {
|
||||||
|
background-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-PUT {
|
||||||
|
background-color: #ffc107;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-DELETE {
|
||||||
|
background-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-PATCH {
|
||||||
|
background-color: #17a2b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-url {
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
word-break: break-all;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-details {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.matched-items {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding: 6px;
|
||||||
|
background: #e7f3ff;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.matched-items-label {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #0066cc;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.matched-item {
|
||||||
|
display: inline-block;
|
||||||
|
background: #667eea;
|
||||||
|
color: white;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 10px;
|
||||||
|
margin-right: 4px;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-body-preview {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding: 6px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #666;
|
||||||
|
max-height: 60px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #888;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #555;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Network Request Monitor</title>
|
||||||
|
<link rel="stylesheet" href="popup.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<h1>Network Monitor</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>Search Items</h2>
|
||||||
|
<div class="search-items-container">
|
||||||
|
<textarea id="searchItemsInput" placeholder="Enter items to search for (one per line) Example: api/users authentication featureFlag"></textarea>
|
||||||
|
<button id="saveSearchItems" class="btn btn-primary">Save Search Items</button>
|
||||||
|
<div id="saveStatus" class="status-message"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>Matched Requests <span id="matchCount" class="badge">0</span></h2>
|
||||||
|
<div class="controls">
|
||||||
|
<button id="refreshRequests" class="btn btn-secondary">Refresh</button>
|
||||||
|
<button id="copyRequests" class="btn btn-success">Copy to Clipboard</button>
|
||||||
|
<button id="clearRequests" class="btn btn-danger">Clear All</button>
|
||||||
|
</div>
|
||||||
|
<div class="auto-clear-container">
|
||||||
|
<label class="checkbox-label">
|
||||||
|
<input type="checkbox" id="autoClearOnNavigate">
|
||||||
|
<span>Clear on page navigation</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="requestsList" class="requests-list">
|
||||||
|
<p class="empty-state">No matches found yet. Add search items above and browse websites.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="popup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
216
src/utils/chrome-extensions/chrome-network-monitor/popup.js
Normal file
216
src/utils/chrome-extensions/chrome-network-monitor/popup.js
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
// Popup script for Network Request Monitor
|
||||||
|
|
||||||
|
let currentTabId = null;
|
||||||
|
|
||||||
|
// Initialize popup
|
||||||
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
// Get current tab
|
||||||
|
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||||
|
currentTabId = tab.id;
|
||||||
|
|
||||||
|
// Load saved search items
|
||||||
|
loadSearchItems();
|
||||||
|
|
||||||
|
// Load matched requests
|
||||||
|
loadRequests();
|
||||||
|
|
||||||
|
// Load auto-clear preference
|
||||||
|
loadAutoClearPreference();
|
||||||
|
|
||||||
|
// Setup event listeners
|
||||||
|
document.getElementById('saveSearchItems').addEventListener('click', saveSearchItems);
|
||||||
|
document.getElementById('refreshRequests').addEventListener('click', loadRequests);
|
||||||
|
document.getElementById('copyRequests').addEventListener('click', copyRequestsToClipboard);
|
||||||
|
document.getElementById('clearRequests').addEventListener('click', clearRequests);
|
||||||
|
document.getElementById('autoClearOnNavigate').addEventListener('change', saveAutoClearPreference);
|
||||||
|
});// Load search items from storage
|
||||||
|
async function loadSearchItems() {
|
||||||
|
const result = await chrome.storage.sync.get(['searchItems']);
|
||||||
|
const searchItems = result.searchItems || [];
|
||||||
|
document.getElementById('searchItemsInput').value = searchItems.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load auto-clear preference
|
||||||
|
async function loadAutoClearPreference() {
|
||||||
|
const result = await chrome.storage.sync.get(['autoClearOnNavigate']);
|
||||||
|
document.getElementById('autoClearOnNavigate').checked = result.autoClearOnNavigate || false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save auto-clear preference
|
||||||
|
async function saveAutoClearPreference() {
|
||||||
|
const autoClear = document.getElementById('autoClearOnNavigate').checked;
|
||||||
|
await chrome.storage.sync.set({ autoClearOnNavigate: autoClear });
|
||||||
|
console.log('Auto-clear preference saved:', autoClear);
|
||||||
|
}// Save search items to storage
|
||||||
|
async function saveSearchItems() {
|
||||||
|
const input = document.getElementById('searchItemsInput').value;
|
||||||
|
const searchItems = input
|
||||||
|
.split('\n')
|
||||||
|
.map(item => item.trim())
|
||||||
|
.filter(item => item.length > 0);
|
||||||
|
|
||||||
|
await chrome.storage.sync.set({ searchItems: searchItems });
|
||||||
|
|
||||||
|
// Show success message
|
||||||
|
const statusEl = document.getElementById('saveStatus');
|
||||||
|
statusEl.textContent = `✓ Saved ${searchItems.length} search item${searchItems.length !== 1 ? 's' : ''}`;
|
||||||
|
setTimeout(() => {
|
||||||
|
statusEl.textContent = '';
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
console.log('Search items saved:', searchItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load matched requests from background
|
||||||
|
async function loadRequests() {
|
||||||
|
chrome.runtime.sendMessage(
|
||||||
|
{ action: 'getRequests', tabId: currentTabId },
|
||||||
|
(response) => {
|
||||||
|
displayRequests(response.requests || []);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display requests in the UI
|
||||||
|
function displayRequests(requests) {
|
||||||
|
const listEl = document.getElementById('requestsList');
|
||||||
|
const countEl = document.getElementById('matchCount');
|
||||||
|
|
||||||
|
countEl.textContent = requests.length;
|
||||||
|
|
||||||
|
if (requests.length === 0) {
|
||||||
|
listEl.innerHTML = '<p class="empty-state">No matches found yet. Add search items above and browse websites.</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by timestamp (newest first)
|
||||||
|
requests.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
|
||||||
|
|
||||||
|
listEl.innerHTML = requests.map(req => createRequestElement(req)).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create HTML for a single request
|
||||||
|
function createRequestElement(request) {
|
||||||
|
const timestamp = new Date(request.timestamp).toLocaleTimeString();
|
||||||
|
const statusCode = request.statusCode ? ` - ${request.statusCode}` : '';
|
||||||
|
|
||||||
|
const matchedItemsHtml = request.matches && request.matches.length > 0
|
||||||
|
? `
|
||||||
|
<div class="matched-items">
|
||||||
|
<div class="matched-items-label">Matched Items:</div>
|
||||||
|
${request.matches.map(item => `<span class="matched-item">${escapeHtml(item)}</span>`).join('')}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
const bodyPreviewHtml = request.requestBody && request.requestBody.length > 0
|
||||||
|
? `<div class="request-body-preview">${escapeHtml(request.requestBody)}</div>`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="request-item">
|
||||||
|
<div class="request-header">
|
||||||
|
<span class="method-badge method-${request.method}">${request.method}</span>
|
||||||
|
<span class="request-url">${escapeHtml(request.url)}</span>
|
||||||
|
</div>
|
||||||
|
<div class="request-details">
|
||||||
|
${timestamp}${statusCode}
|
||||||
|
</div>
|
||||||
|
${matchedItemsHtml}
|
||||||
|
${bodyPreviewHtml}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy requests to clipboard
|
||||||
|
async function copyRequestsToClipboard() {
|
||||||
|
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||||
|
|
||||||
|
chrome.runtime.sendMessage(
|
||||||
|
{ action: 'getRequests', tabId: currentTabId },
|
||||||
|
async (response) => {
|
||||||
|
const requests = response.requests || [];
|
||||||
|
|
||||||
|
if (requests.length === 0) {
|
||||||
|
alert('No requests to copy');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group URLs by matched keywords
|
||||||
|
const matchedUrlsByKeyword = new Map();
|
||||||
|
|
||||||
|
requests.forEach(req => {
|
||||||
|
if (req.matches && req.matches.length > 0) {
|
||||||
|
req.matches.forEach(match => {
|
||||||
|
if (!matchedUrlsByKeyword.has(match)) {
|
||||||
|
matchedUrlsByKeyword.set(match, []);
|
||||||
|
}
|
||||||
|
// Add URL if not already in the list for this keyword
|
||||||
|
if (!matchedUrlsByKeyword.get(match).includes(req.url)) {
|
||||||
|
matchedUrlsByKeyword.get(match).push(req.url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Format the output
|
||||||
|
const pageTitle = tab.title || 'Unknown Page';
|
||||||
|
const pageUrl = tab.url || 'Unknown URL';
|
||||||
|
|
||||||
|
let output = `${pageTitle} - ${pageUrl}\n`;
|
||||||
|
|
||||||
|
const sortedMatches = Array.from(matchedUrlsByKeyword.keys()).sort();
|
||||||
|
sortedMatches.forEach(match => {
|
||||||
|
output += `- ${match}\n`;
|
||||||
|
const urls = matchedUrlsByKeyword.get(match);
|
||||||
|
|
||||||
|
// Add sub-bullets for each URL
|
||||||
|
urls.forEach(url => {
|
||||||
|
output += ` - ${url}\n`;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Copy to clipboard
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(output);
|
||||||
|
|
||||||
|
// Show success feedback
|
||||||
|
const copyBtn = document.getElementById('copyRequests');
|
||||||
|
const originalText = copyBtn.textContent;
|
||||||
|
copyBtn.textContent = '✓ Copied!';
|
||||||
|
copyBtn.style.backgroundColor = '#218838';
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
copyBtn.textContent = originalText;
|
||||||
|
copyBtn.style.backgroundColor = '';
|
||||||
|
}, 2000);
|
||||||
|
} catch (err) {
|
||||||
|
alert('Failed to copy to clipboard: ' + err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear all requests
|
||||||
|
async function clearRequests() {
|
||||||
|
chrome.runtime.sendMessage(
|
||||||
|
{ action: 'clearRequests', tabId: currentTabId },
|
||||||
|
(response) => {
|
||||||
|
if (response.success) {
|
||||||
|
loadRequests();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape HTML to prevent XSS
|
||||||
|
function escapeHtml(text) {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.textContent = text;
|
||||||
|
return div.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-refresh every 2 seconds
|
||||||
|
setInterval(() => {
|
||||||
|
loadRequests();
|
||||||
|
}, 2000);
|
||||||
68
src/utils/git/updateReadme.js
Normal file
68
src/utils/git/updateReadme.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* This file is responsible for updating the README file with file links and descriptions.
|
||||||
|
* It reads the files in the specified directory, extracts their descriptions, and generates
|
||||||
|
* markdown links for each file. Then, it updates the README file with the generated links
|
||||||
|
* and descriptions.
|
||||||
|
*/
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
const resolvedPath = path.resolve();
|
||||||
|
console.log(resolvedPath);
|
||||||
|
|
||||||
|
const utilsDir = path.join(resolvedPath, 'src/utils');
|
||||||
|
const readmePath = path.join(resolvedPath, 'README.md');
|
||||||
|
|
||||||
|
fs.readdir(utilsDir, (err, files) => {
|
||||||
|
function readDirectory(dir) {
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
const fileLinks = [];
|
||||||
|
|
||||||
|
files.forEach((file) => {
|
||||||
|
const filePath = path.join(dir, file);
|
||||||
|
const stats = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (stats.isFile()) {
|
||||||
|
const fileContent = fs.readFileSync(filePath, 'utf8');
|
||||||
|
const description = getFileDescription(fileContent);
|
||||||
|
fileLinks.push(`## [${file}](${path.relative(resolvedPath, filePath)})\n${description}`);
|
||||||
|
} else if (stats.isDirectory()) {
|
||||||
|
fileLinks.push(...readDirectory(filePath));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return fileLinks;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileLinks = readDirectory(utilsDir);
|
||||||
|
|
||||||
|
const readmeContent = fs.readFileSync(readmePath, 'utf8');
|
||||||
|
let updatedReadmeContent = updateReadmeContent(readmeContent, fileLinks);
|
||||||
|
fs.writeFileSync(readmePath, updatedReadmeContent, 'utf8');
|
||||||
|
|
||||||
|
console.log('README updated successfully!');
|
||||||
|
});
|
||||||
|
|
||||||
|
function getFileDescription(fileContent) {
|
||||||
|
// Extract the description from the function comment in the file
|
||||||
|
// You can use regular expressions or any other method to extract the description
|
||||||
|
// Replace the following line with your implementation
|
||||||
|
const descriptionRegex = /\/\*(.*?)\*\//s;
|
||||||
|
const match = fileContent.match(descriptionRegex);
|
||||||
|
const description = match ? match[1].trim().replace(/^\s*\* ?/gm, '') : 'No Description Provided';
|
||||||
|
// const description = match ? match[1].trim().replace(/^\*/gm, '') : 'No Description Provided';
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateReadmeContent(readmeContent, fileLinks) {
|
||||||
|
const readmeSummaryIndex = readmeContent.indexOf('# File Summary');
|
||||||
|
if (readmeSummaryIndex !== -1) {
|
||||||
|
// If '# File Summary' is found, keep everything before it
|
||||||
|
readmeContent = readmeContent.slice(0, readmeSummaryIndex);
|
||||||
|
}
|
||||||
|
// Append the new '# File Summary' section
|
||||||
|
readmeContent += '# File Summary\n\n' + fileLinks.join('\n\n');
|
||||||
|
return readmeContent;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user