-
Notifications
You must be signed in to change notification settings - Fork 6
New Admin UI #524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
New Admin UI #524
Changes from 8 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
e46c370
New Admin UI
aulme 85c52a4
[CI Pipeline] Released Snapshot version: 6.3.1-alpha-187-SNAPSHOT
51b90c5
Merge branch 'main' into aul-UID2-5549-ui-refactor
aulme 1d51841
further refactoring
aulme 3738eb3
Roles inputs
aulme 82ee89d
componentizing
aulme 6c7c258
[CI Pipeline] Released Snapshot version: 6.5.8-alpha-188-SNAPSHOT
c5f7f44
Add Readme for the new UI
aulme e08da8e
Addressing feedback
aulme 462c127
Merge branch 'main' into aul-UID2-5549-ui-refactor
aulme 883c084
remove unused function
aulme File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,10 +21,6 @@ When running locally, set the `is_auth_disabled` flag to `true` in [local-config | |
|
|
||
| If you want to test with Okta OAuth, set the `is_auth_disabled` flag to `false`, and fill in the `okta_client_secret` with the value under "Okta localhost deployment" in 1Password. | ||
|
|
||
| ### Working on the UI | ||
|
|
||
| Per the above setup steps, the UI runs on `http://localhost:8089/`. To see your local UI changes reflected in the browser, you will need to hard reload (`Crtl+Shift+R`) while on the specific web page you have changed. | ||
|
|
||
| ## V2 API | ||
|
|
||
| The v2 API is based on individual route provider classes. Each class should provide exactly one endpoint and must implement IRouteProvider or IBlockingRouteProvider. | ||
|
|
@@ -36,3 +32,174 @@ The v2 API is based on individual route provider classes. Each class should prov | |
| IRouteProvider requires a `getHandler` method, which should return a valid handler function - see `GetClientSideKeypairsBySite.java`. This method *must* be annotated with the Path, Method, and Roles annotations. | ||
|
|
||
| The route handler will automatically be wrapped by the Auth middleware based on the roles specified in the Roles annotation. | ||
|
|
||
| ## Working on the UI | ||
| Per the above setup steps, the UI runs on `http://localhost:8089/`. To see your local UI changes reflected in the browser, you will need to hard reload (`Crtl+Shift+R`) while on the specific web page you have changed. | ||
|
|
||
| ### Page setup | ||
| ```html | ||
| <html> | ||
| <head> | ||
| <!-- We use Unicode symbols for icons so need UTF-8 --> | ||
| <meta charset="UTF-8"> | ||
| <link rel="stylesheet" href="/css/style.css"> | ||
| </head> | ||
| <body> | ||
|
|
||
| <div class="main-content"> | ||
| <!-- Operations and controls will be added by `initializeOperations` here --> | ||
| <div class="operations-container"></div> | ||
|
|
||
| <!-- Both success and error output will be added by `initializeOutput` hedre --> | ||
| <div class="output-container"></div> | ||
| </div> | ||
|
|
||
| <script type="module"> | ||
| document.addEventListener('DOMContentLoaded', function () { | ||
| import { initializeOperations } from '/js/component/operations.js'; | ||
| import { initializeOutput } from '/js/component/output.js'; | ||
|
|
||
| const operationConfig = { | ||
| read: [ // Read-only operations (don't modify data) | ||
| // See Operations example below | ||
| ], | ||
| write: [ // Write operations (modify data) | ||
| // ... | ||
| ], | ||
| danger: [// Dangerous operations (require explicit confirmation modal) | ||
gmsdelmundo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // ... | ||
| ] | ||
| } | ||
|
|
||
| initializeOperations(operationConfig); | ||
| initializeOutput(); | ||
| }); | ||
| } | ||
| </script> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| ### Operations | ||
| ```javascript | ||
| const myOperation = { | ||
| id: 'operationId', // Required: Unique identifier | ||
| title: 'Operation Title', // Required: Display name | ||
| role: 'maintainer', // Required: `maintainer`, `elevated` or `superuser` | ||
| inputs: [ // Optional: Inputs (see below) | ||
| { | ||
| name: 'field1', // Value of this input will be available as property matching name on `inputs` object below. | ||
| label: 'Field 1', // Shown on the UI above the field | ||
| type: 'text' // Optional, text by default | ||
| } | ||
| ], | ||
| description: 'text', // Optional: Description will appear within the accordion | ||
| confirmationText: 'text', // Optional: Danger zone confirmation text, will replace stock text if used. Only works in danger zone. | ||
| apiCall: { // Optional: API configuration | ||
| method: 'POST', | ||
| url: '', // Either hardcore URL here or use `getUrl` below. | ||
| getUrl: (inputs) => { // Either construct a URL from the inputs or use `url` above. | ||
| return `/api/my/api?field1=${encodeURIComponent(inputs.field1)}` | ||
| }, | ||
| getPayload: (inputs) => { // Optional: Construct a JS object that will be sent as body | ||
| return { field1: inputs.field1 }; | ||
| } | ||
| }, | ||
| preProcess: async (inputs) => inputs, // Optional: Run before getUrl/getPayload and the API call | ||
|
||
| postProcess: async (data, inputs) => data // Optional: Run after apiCall, if you want to adjust the response | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| ### Inputs | ||
| - Inputs on the same page that share a `name` will have their values synced. | ||
|
|
||
| #### text (default) | ||
| Basic small text input | ||
| ```javascript | ||
| const myText = { | ||
| name: 'fieldName', | ||
| label: 'Field Label', | ||
| required: true, // Optional: If required, Execute won't be enable until filled. Default false. | ||
gmsdelmundo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| size: 2, // Optional: grid span 1-3, grid has 3 columns. Default 1. | ||
| placeholder: 'Enter text', // Optional | ||
| defaultValue: 'default' // Optional | ||
| }; | ||
| ``` | ||
|
|
||
| #### multi-line | ||
| A larger multi-line text input box | ||
| ```javascript | ||
| const myTextArea = { | ||
| name: 'textArea', | ||
| type: 'multi-line', | ||
| label: 'Multi-line Text', | ||
| placeholder: 'Enter text...', | ||
| defaultValue: 'default text' | ||
| }; | ||
| ``` | ||
|
|
||
| #### number | ||
| Number-specific input, won't allow non-number text | ||
| ```javascript | ||
| const myNum = { | ||
| name: 'numField', | ||
| type: 'number', | ||
| label: 'Number Field' | ||
| }; | ||
| ``` | ||
|
|
||
| #### date | ||
| Date-specific input with date picker | ||
| ```javascript | ||
| const myDate = { | ||
| name: 'dateField', | ||
| type: 'date', | ||
| defaultValue: '2024-01-01' | ||
| }; | ||
| ``` | ||
|
|
||
| #### checkbox | ||
| ```javascript | ||
| const myCheckbox = { | ||
| name: 'boolField', | ||
| type: 'checkbox', | ||
| label: 'Is it true?', | ||
| defaultValue: true | ||
| }; | ||
| ``` | ||
|
|
||
| #### select | ||
| Dropdown to select one option from a list | ||
| ```javascript | ||
| const myDropdown = { | ||
| name: 'Dropdown', | ||
| type: 'select', | ||
| label: 'Select Option', | ||
| options: [ | ||
| 'simple', // Can pass as string if option values are same as UI text | ||
|
||
| { value: 'val', label: 'Display' } // Or as Objects if they are different | ||
| ], | ||
| defaultValue: 'val' | ||
| }; | ||
| ``` | ||
|
|
||
| #### multi-select | ||
| Multiple checkboxes to allow selecting more than one option | ||
|
|
||
| ```javascript | ||
| const myMultiSelect = { | ||
| name: 'Multi Select', | ||
| type: 'multi-select', | ||
| label: 'Multiple Options', | ||
| required: true, | ||
| options: [ | ||
| { | ||
| value: 'OPTION_1', | ||
| label: 'Option One', | ||
| hint: 'Tooltip explanation' // Optional, appear as info icons next to options | ||
| } | ||
| ], | ||
| defaultValue: ['OPTION_1'] // Array or comma-separated string | ||
| } | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.