Compare commits

...
104 Commits
Author SHA1 Message Date
Dharini Jeeva 2900692c6c chore: bump up release version and Update change log (#1141)
* chore: 🤖 update to changelog and release version
2022-06-20 13:15:34 -07:00
Cameron PereraandDharini Jeeva 193a7e9600 refactor: 💡 Remove template file to fix onboarding flow titles (#1148)
Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>
2022-06-20 12:01:25 -05:00
Dharini Jeeva 6b3091ea1b chore: 🤖 update to credential source (#1146) 2022-06-20 09:45:50 -07:00
Randall Morey 26baf8a80b fix: grant scope field should be functional (#1147) 2022-06-20 12:28:13 -04:00
Randall Moreyanddharini 4ef66fdd29 Add minimum support for static credential stores to admin UI (#1145)
* cred store read ability

* filter out static cred stores and credentials from credential libraries

* chore: 🤖 finish up minimum static cred store support

Co-authored-by: dharini <dharini@hashicorp.com>
2022-06-18 10:56:25 -04:00
Cameron Perera 52904dc639 Chore add onboarding role (#1142)
* chore: generate a role authorized to access the generated onboarding target
2022-06-16 16:11:11 -07:00
Cameron Perera f3a5ef5b7c refactor: 💡 Update routing to use project id in quick-start (#1140)
✅ Closes: ICU-4821
2022-06-15 15:06:09 -05:00
Randall Morey 7d8012ef1f chore: apply darker color theme to sidebar (#1139)
* chore: apply darker color theme to sidebar

* chore: hide global footer for now due to sidebar change
2022-06-15 14:27:08 -05:00
Cameron Perera 18434d4203 chore: 🤖 Disable ssh feature work (#1138)
Disable ssh feature
2022-06-15 10:42:49 -07:00
Cameron Perera d7e458ab85 refactor: 💡 Remove default value for IP address and port (#1137)
* refactor: 💡 Remove default value for IP address and port
2022-06-14 20:39:50 -07:00
Cameron Perera c5416e770a feat: 🎸 Add Controller URL component to Success screen (#1135)
* feat: 🎸 Add Controller URL component to Success screen

✅ Closes: ICU-4785

* style: 💄 Update Success screen styles to match wireframe

* refactor: 💡 Update class names to be more descriptive

* refactor: 💡 Update styles for Success card

* test: 💍 Fix failing test
2022-06-14 16:36:11 -05:00
Dharini Jeeva 2bb1c9cfec Chore onboarding route (#1136)
* fix: onboarding redirects
2022-06-14 14:21:48 -07:00
Dharini Jeeva 8bdd4416fc transition to target lists when the resource creation is successful (#1134)
* feat: 🎸  redirect the user to target lists within the project after successfully creating a resource.
2022-06-14 12:32:04 -07:00
Cameron Pereraanddharini a5da593f07 Create successful resource creation screen (#1132)
* feat: 🎸 Create successful resource creation screen

Create a screen with helpful information about Boundary once resources
have been created for the user

✅ Closes: ICU-4558

* style: 💄 remove stale comment

* chore: 🤖 resolve conflicts and merge main

Co-authored-by: dharini <dharini@hashicorp.com>
2022-06-14 09:33:51 -05:00
Randall MoreyandCameron Perera 15dc735322 chore: move onboarding to top level (#1131)
* chore: move onboarding to top level

* chore: add types

* Update ui/admin/app/routes/onboarding.js

Co-authored-by: Cameron Perera <cameron.perera@hashicorp.com>

* fix: broken paths

* chore: fix broken success route and simplify error handling

* fix: tests

Co-authored-by: Cameron Perera <cameron.perera@hashicorp.com>
2022-06-13 16:38:18 -04:00
Dharini Jeeva d69b0f90d8 Icu 4556 create a quick setup screen (#1129)
* feat: 🎸 Create a resource onboarding form
2022-06-10 15:43:20 -07:00
Cameron Perera 0bb5989259 feat: 🎸 Create form to choose onboarding guide path (#1124)
* feat: 🎸 Create onboarding welcome form
2022-06-09 15:47:07 -07:00
Carlos Alcaide Corvo 106999746f docs: ✏️ Update docs for yarn scripts (#1101) 2022-06-08 14:05:56 -07:00
Carlos Alcaide Corvo d60ae81bdc Fix rose peer dependencies (#1128)
Fix Rose peer dependency warnings
2022-06-08 09:25:28 -07:00
Carlos Alcaide Corvo c7cb1fbbd8 chore: 🤖 Update electron from 13 to 14 (#1125)
Update electron from 13 to 14
2022-06-08 09:09:18 -07:00
Dharini Jeeva 8a05dbbc56 create new image component (#1127)
* feat:  create image component
2022-06-08 08:45:59 -07:00
Randall Morey dc78fe9028 Chore include terminated (#1126)
* chore: 🤖 add include_terminated=true when filtering terminated

* chore: 🤖 add include_terminated=true when filtering terminated
2022-06-07 15:40:33 -04:00
Randall MoreyandDharini Jeeva 24f630f084 Chore onboarding routing logic (#1123)
* chore: 🤖 stub out onboarding routes

* chore: initial onboarding routing logic

* chore: initial routing logic and resource creation

* chore: route "manual" to new org

* Update en-us.yaml

* fix: linting

Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>
2022-06-03 13:25:53 -04:00
Cameron Perera d4ac887f7a Create CODEOWNERS file (#1122)
* chore: Create CODEOWNERS file

* chore: update CODEOWNERS

* chore: 🤖 finalize CODEOWNERS changes
2022-06-03 09:44:45 -05:00
Randall Morey 9fe8ce2c00 chore: 🤖 stub out onboarding routes (#1118) 2022-06-02 08:48:34 -04:00
Randall Morey af3cfb7298 chore: 🤖 generate more realistic mock IDs (#1117)
* chore: 🤖 generate more realistic mock IDs

* Update id.js
2022-06-01 14:02:18 -04:00
Zhihe Li df609dcf2c refactor: 💡 Update deprecated new window handler (#1111)
✅ Closes: ICU-4037
2022-05-20 12:53:52 -04:00
Zhihe Li 1b9f774937 fix: 🐛 Use more common hasOwnProperty and don't modify payload (#1112) 2022-05-19 17:52:10 -04:00
Randall Morey 509215f787 chore: 🤖 display auth method names in auth form, if available (#1113) 2022-05-19 15:56:48 -04:00
Carlos Alcaide Corvo 698160d423 refactor: 💡 Rename Admin UI enterprise artifact (#1110)
Rename Admin UI generated artifact for the enterprise edition.
2022-05-17 07:03:22 -07:00
Cameron PereraandDharini Jeeva 12b18510b9 refactor: 💡 Update language to use Sign In and Sign Out (#1109)
* refactor: 💡 Update language to use Sign In and Sign Out

Update authenticate/deauthenticate language to sign in and sign out
respectively

✅ Closes: ICU-3941

* refactor: 💡 Change translation keys back to (de)authenticate

Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>
2022-05-16 17:28:45 -05:00
aa52b6f9bc fix: 🐛 Update validateOrigin to throw error on bad request (#1107)
* fix: 🐛 Update validateOrigin to throw error on bad request

If the result from netRequestPromise is successful but a not a 200
response, validateOrigin will throw an error

✅ Closes: ICU-4238

* Update ui/desktop/electron-app/src/models/runtime-settings.js

Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>

* refactor: 💡 Add comment as to why we don't throw error for 3xxs

* Update ui/desktop/electron-app/src/models/runtime-settings.js

Co-authored-by: Randall Morey <randall@randallmorey.com>

* Update ui/desktop/electron-app/src/models/runtime-settings.js

Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>

Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>
Co-authored-by: Randall Morey <randall@randallmorey.com>
2022-05-16 12:20:56 -05:00
Dharini Jeeva ee47f8e19e fix: 🐛 add featureflag to target creation template (#1108)
* fix: 🐛 add featureflag to target creation template

* refactor: 💡 remove else block
2022-05-13 10:57:52 -07:00
Zhihe Li 97196368cb Fix Users page not updating fields correctly (#1105)
* fix: 🐛 Normalize update responses to track removed fields

✅ Closes: ICU-4189
2022-05-12 10:16:14 -04:00
Carlos Alcaide Corvo 7e792d3f76 Refactor UI generated artifacts creation. (#1104)
* Refactor UI generated artifacts creation. Now we generate OSS and enterprise specific artifacts

* Split builds in two separate jobs
2022-05-11 13:28:30 -07:00
Randall Morey f4df337761 chore: update github actions validator to depend on previous jobs (#1081) 2022-05-06 10:32:11 -04:00
Cameron Perera de44863d02 chore: 🤖 Add lzma-native to resolutions (#1103)
* chore: 🤖 Add lzma-native and appdmg to resolutions

* chore: 🤖 Remove appdmg resolution from electron-app

Tested that CI steps passed.
2022-05-05 17:35:53 -05:00
Cameron Perera e3f9feb474 Update polling interval to 300 seconds (5 minutes) (#1102)
Update polling interval to 300 seconds (5 minutes)
2022-05-05 11:43:07 -05:00
Carlos Alcaide Corvo 57410b7bb6 refactor: 💡 Avoid lint warning (#1095)
* refactor: 💡 Avoid lint warning
2022-05-05 08:28:41 -07:00
Carlos Alcaide Corvo 5e2c6ca0fd feat: 🎸 Add feature editions (#1094)
* feat: 🎸 Add feature editions
2022-05-05 07:42:02 -07:00
Carlos Alcaide Corvo eb36cde137 Update polling intervarl (#1100) 2022-05-04 09:51:16 -07:00
Cameron PereraandZhihe Li ccb266ea7c chore: 🤖 bump binary version and update changelog (#1099)
* chore: 🤖 bump binary version and update changelog

* chore: 🤖 Update Desktop app release date

* chore: 🤖 Update release date

Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>
2022-05-04 10:32:42 -05:00
ZedandRandall Morey 8545697b43 Add toolbar regions to align refresh button to the right (#1098)
* feat: 🎸 implement toolbar regions and apply to admin sessions

* feat: 🎸 Add toolbar regions for desktop sessions and targets

✅ Closes: ICU-4198

Co-authored-by: Randall Morey <randall@randallmorey.com>
2022-05-03 09:46:47 -04:00
Zed a8ae8d28df fix: 🐛 Reduce extra padding in tables (#1091)
✅ Closes: ICU-4046
2022-05-02 10:14:21 -04:00
Cameron Perera 952b894a32 feat: 🎸 Add ToolbarRefresher component to targets in desktop (#1093)
✅ Closes: ICU-4134
2022-04-29 18:06:11 -05:00
Cameron Perera 6f449b3b9b feat: 🎸 Add ToolbarRefresher component to sessions in admin (#1092)
✅ Closes: ICU-4133
2022-04-29 17:54:08 -05:00
Cameron PereraandRandall Morey 0f3c2f043b style: 💄 Update Refresh Button to animate when loading (#1089)
* style: 💄 Update Refresh Button to animate when loading

* refactor: 💡 Move temporary animation styles to app level styles

Co-authored-by: Randall Morey <randall@randallmorey.com>
2022-04-29 15:29:53 -05:00
Dharini Jeeva 82c94518d9 feat: refresh sessions view in admin ui (#1078) 2022-04-29 14:28:50 -04:00
Randall Morey 68a269efac feature: add toolbar refresher component (#1088) 2022-04-29 13:51:47 -04:00
Zed 75ef323e6d fix: 🐛 Desktop client not correctly loading ember app url (#1090) 2022-04-29 13:38:25 -04:00
Carlos Alcaide Corvo ccde5e88da fix: 🐛 Mac os window lifecycle (#1067) 2022-04-29 09:03:40 -07:00
Carlos Alcaide Corvo 1071241604 chore: 🤖 Increase polling time Admin UI (#1085) 2022-04-29 07:47:03 -07:00
Zed 316f0907fc fix: 🐛 Fix scrollbar for the sidebar in desktop client (#1076)
Fixed scroll bar always appearing in sidebar on macOS for desktop client
and sidebar not staying fixed in windows and linux

✅ Closes: ICU-4143
2022-04-29 10:16:34 -04:00
Cameron Perera 3bdae6dce8 feat: 🎸 refresh targets list view in desktop (#1087)
✅ Closes: ICU-4024
2022-04-28 17:35:52 -05:00
Carlos Alcaide Corvo 367545fd4d refactor: 💡 Encapsulate desktop client window creation (#1066)
Encapsulate desktop client window creation to reuse the creation of new
windows.
2022-04-28 15:23:43 -07:00
Randall Morey 702ad64716 Style toolbar buttons (#1086)
* chore: 🤖 move loading-button component to core addon

* style: toolbar buttons should align with Structure

* fix: buttons should have consistent font
2022-04-28 17:59:43 -04:00
Randall Morey 043dbc3736 chore: 🤖 move loading-button component to core addon (#1083) 2022-04-28 17:49:03 -04:00
Cameron Perera 01e4ec0a07 feat: 🎸 Add minimum refresh time to refresh button for sessions (#1077) 2022-04-28 16:35:46 -04:00
Randall Morey a7b3da2231 feat: 🎸 implement live relative datetime component (#1080) 2022-04-28 16:23:44 -04:00
Randall Morey de6416efbd feat: 🎸 add non-interactive rose toolbar info component (#1075) 2022-04-28 16:01:50 -04:00
76befc0c1d chore: 🤖 Increaase polling time desktop client (#1074)
Increase polling time within desktop client.

Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>
Co-authored-by: Randall Morey <randall@randallmorey.com>
2022-04-28 15:48:33 -04:00
Carlos Alcaide Corvo f71d01902a Revert "feat: 🎸 Add feature editions (#1072)" (#1079)
This reverts commit 56d84d652b.
2022-04-28 12:14:27 -07:00
Carlos Alcaide Corvo 56d84d652b feat: 🎸 Add feature editions (#1072)
Add feature editions
2022-04-28 10:23:35 -07:00
Dharini Jeeva 9cf216179a feat: refresh sessions list view in desktop (#1069)
* feat: 🎸 add a refresh button to sessions list view in desktop
2022-04-28 08:49:37 -07:00
Zed 050cfdd056 fix: 🐛 Fix scrollbars not being dark in dark mode (#1068)
✅ Closes: ICU-4022
2022-04-27 18:18:24 -04:00
Carlos Alcaide Corvo 79fb0db882 docs: ✏️ Update node supported versions (#1071)
Update node supported versions
2022-04-26 17:06:10 -07:00
Cameron Perera a2c6bc643d chore: 🤖 Update the .template-lintrc.js file in addons/rose (#1073)
✅ Closes: ICU-4123
2022-04-26 14:56:13 -05:00
Zed 07ed40ce03 fix: 🐛 Adjusted dark mode gray scale and fixed radio card colors (#1065)
Adjusted dark mode gray scale to be a bit darker and 
made the active selected radio card lighter in dark mode

✅ Closes: ICU-4021
2022-04-26 11:28:02 -04:00
Cameron Perera e0cbbefb41 fix: 🐛 Fix new target navigation issue (#1070)
Fix issue where trying to leave the new target form via the discard
changes dialog would cause the user to have to refresh screen.

✅ Closes: ICU-4047
2022-04-26 08:21:11 -05:00
Carlos Alcaide Corvo 2a1e4858fa chore: 🤖 Update Electron from 12.x to 13.x (#1063) 2022-04-21 12:46:41 -07:00
Cameron Perera 7b154b223a feat: 🎸 Update Target types help text (#1064)
* feat: 🎸 Update Target types help text

✅ Closes: ICU-4014

* refactor: 💡 Update how radio cards determine height

Radio cards will now fill up the entire height of the fieldset they are
in

* style: 💄 Update radio card padding
2022-04-21 13:51:47 -05:00
Carlos Alcaide Corvo 550cadf612 Revert "fix: 🐛 Disable polling for sessions on Desktop (#1058)" (#1062)
This reverts commit 26e074dbef.
2022-04-19 13:22:47 -07:00
Carlos Alcaide Corvo 95cece1481 Revert "fix: 🐛 Disable polling for targets on Desktop (#1059)" (#1061)
This reverts commit 6249e945b8.
2022-04-19 13:06:42 -07:00
Carlos Alcaide Corvo 94a3c1fcf1 Revert "disable polling in admin UI (#1057)" (#1060)
This reverts commit 90c9fa8b73.
2022-04-19 12:51:03 -07:00
Cameron PereraandDharini Jeeva f2b53d2f45 chore: 🤖 Updated pr-template to include Jira base url (#1055)
Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>
2022-04-19 09:35:14 -05:00
Cameron Perera 6249e945b8 fix: 🐛 Disable polling for targets on Desktop (#1059)
✅ Closes: ICU-3954
2022-04-19 09:22:13 -05:00
Cameron Perera 26e074dbef fix: 🐛 Disable polling for sessions on Desktop (#1058)
✅ Closes: ICU-3953
2022-04-19 09:10:09 -05:00
Dharini Jeeva 90c9fa8b73 disable polling in admin UI (#1057)
* fix: 🐛 disable sessions polling

* increase sessions count

* fix: 🐛 undo mirage test
2022-04-18 18:08:23 -04:00
Zed 215bf00407 test: 💍 Verify target worker filter is created correctly (#1056)
✅ Closes: ICU-3893
2022-04-15 16:00:03 -04:00
Cameron Perera d8efefc2b3 test: 💍 Verify target worker filter can be edited (#1054)
✅ Closes: ICU-3892
2022-04-15 13:52:31 -05:00
Cameron Perera 95ed2c0fda feat: 🎸 Add worker filter field in target form (#1053)
* feat: 🎸 Add worker filter field in target form

✅ Closes: ICU-3891

* feat: 🎸 Add Learn More link to Worker Filter input field
2022-04-14 15:27:36 -05:00
Carlos Alcaide Corvo 8776b46277 Chore update eslint (#1045)
Update eslint and eslint-plugin-ember to their latest versions.
2022-04-13 14:17:46 -07:00
Zed 670f38df74 feat: 🎸 Add mirage data for the worker_filter (#1051)
* feat: 🎸 Add mirage data for the "worker_filter" attribute

✅ Closes: ICU-3888
2022-04-12 17:42:13 -04:00
Cameron PereraandDharini Jeeva 226475a47d feat: 🎸 Add "worker_filter" attribute to target model (#1049)
* feat: 🎸 Add "worker_filter" attribute to target model

✅ Closes: ICU-3887

* feat: 🎸 Add missing attribute description for worker_filter

* feat: 🎸 Update worker_filter description

Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>
2022-04-12 16:16:51 -05:00
Dharini Jeeva 1072be1eff refactor: 💡 improve target creation (#1050)
* refactor: 💡 improve target creation UX
2022-04-12 14:05:16 -07:00
Carlos Alcaide Corvo 22d8af72ae Feat add build admin UI workflow (#1048)
* chore: 🤖 Add build admin UI workflow
2022-04-08 14:57:20 -07:00
Cameron Perera 79596010e9 feat: 🎸 Update Success Dialog when connecting to target (#1046)
Updated the Success Dialog in desktop app when connecting to a target to
dynamically show target type

✅ Closes: ICU-3647
2022-04-08 14:15:32 -05:00
Carlos Alcaide Corvo 8e884d53ae Revert "chore: 🤖 Add build admin UI workflow (#1043)" (#1047)
This reverts commit 505820eb6c.
2022-04-08 09:06:22 -07:00
Carlos Alcaide Corvo 505820eb6c chore: 🤖 Add build admin UI workflow (#1043)
* chore: 🤖 Add build admin UI workflow
2022-04-08 08:41:48 -07:00
Carlos Alcaide Corvo 4b09c7014b Chore update babel parser (#1044)
Update babel-parser and dependencies.
2022-04-07 14:39:59 -07:00
Cameron Perera f4535c8307 test: 💍 Add tests specific to SSH target creation
* test: 💍 Add tests specific to SSH target creation

* test: 💍 creating new SSH target when enabled or disabled

Verifying the link to create new SSH targets is not present when
ssh-targets is not enabled

* refactor: update create targets acceptance test names
2022-04-06 09:30:49 -05:00
Dharini Jeeva 9fae8f2a9f feat: create ssh type target in admin-ui (#1027)
* feat: 🎸 create ssh type target in admin-UI
2022-03-31 15:34:24 -07:00
Carlos Alcaide Corvo a7bcc0c332 chore: 🤖 Update plist version on desktop (#1040)
Update plist version resolutions on desktop as per dependabot alert.
2022-03-31 10:40:57 -07:00
Dharini Jeeva f877477cd7 feat: 🎸 update target route to support ssh type (#1038)
* feat: 🎸 update target route to support ssh type
2022-03-31 09:50:03 -07:00
Carlos Alcaide Corvo 335df22a38 chore: 🤖 Update plist on admin resolutions (#1039)
Update plist version on admin resolutions as per dependabot alert.
2022-03-31 09:06:34 -07:00
Carlos Alcaide Corvo ca09b538f7 chore: 🤖 Add minimist to desktop resolutions (#1034)
Add minimist to desktop resolutions as per dependabot alert.
2022-03-28 14:10:33 -07:00
Carlos Alcaide Corvo 68ba653984 chore: 🤖 Add minimist to admin resolutions (#1032)
Add minimist to admin resolutions
2022-03-28 13:47:32 -07:00
Michele Degges 5a90533a2e [RelAPI Onboarding] Add release API metadata file (#1031) 2022-03-24 13:52:26 -07:00
Carlos Alcaide Corvo 3d7b8537e1 chore: 🤖 Resolutions ansi-html (#1030)
Add ansi-html to resolutions
2022-03-22 07:23:11 -07:00
Carlos Alcaide Corvo 8d6669c8a1 chore: 🤖 Update git-cz (#1029)
Update git-cz
2022-03-18 14:12:35 -07:00
Dharini Jeeva 7c3f57c7fa chore: display sync interval seconds on host-set plugin forms (#1014)
* chore: 🤖 display sync_interval_seconds toggle on the forms

* chore: 🤖 remove comment

* chore: 🤖 remove extra spacing

* fix: 🐛 update title and add a description for sync_interval

* fix: 🐛 lint in translation

* chore: 🤖 fix typo, remove duplicate code

* chore: 🤖 simplify sync interval field, remove toggling

* fix: 🐛 use correct error code

* fix: 🐛 move sync interval translation to forms

* fix: 🐛 use appropiate translations label
2022-03-17 13:49:18 -07:00
Cameron Perera 2543d14c5a Chore: Add a PR template file (#1028)
* chore: 🤖 Add a PR template file

* chore: 🤖 update pr template

* chore: 🤖 final pr template update

* Update .github/pull_request_template.md

Move JIRA ticket link to the top
2022-03-17 14:00:44 -05:00
Carlos Alcaide Corvo fe7cb014a0 feat: 🎸 Add default custom Model for mirage (#1013)
* feat: 🎸 Add default custom Model for mirage
2022-03-17 11:05:41 -07:00
Carlos Alcaide Corvo adcfb00131 chore: 🤖 Bump binary version and update changelog (#1026)
Bump binary version and update changelog.
2022-03-16 14:41:41 -07:00
247 changed files with 4230 additions and 1710 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Anyone attached to this rule will always been assigned to a pull request
* @hashicorp/boundary-ui
+17
View File
@@ -0,0 +1,17 @@
:tickets: [Jira ticket](https://hashicorp.atlassian.net/browse/JIRA_TICKET_NUMBER)
## Description
<!--
Replace PATH_TO_FEATURE with Vercel link
-->
:technologist: [Admin preview](PATH_TO_FEATURE)
:rose: [Rose preview](PATH_TO_FEATURE)
:desktop_computer: [Desktop preview](PATH_TO_FEATURE)
<!-- Add a brief description of changes here. Include any other necessary relevant links -->
### Screenshots (if appropriate):
+76
View File
@@ -0,0 +1,76 @@
name: Build Admin UI
on:
push:
branches:
- main
jobs:
dependencies:
name: Install dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@v3
with:
node-version: '16.x'
- run: yarn install
build-admin-ui-oss:
name: Build Admin UI OSS
needs: [dependencies]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- name: Build
uses: actions/setup-node@v3
with:
node-version: '16.x'
if: steps.node-modules-cache.outputs.cache-hit != 'true'
- run: yarn run build:ui:admin:oss
- name: Upload artifact admin-ui
uses: actions/upload-artifact@v3
with:
name: admin-ui
path: ./ui/admin/dist/
- name: Upload artifact Admin UI OSS
uses: actions/upload-artifact@v3
with:
name: admin-ui-oss
path: ./ui/admin/dist/
build-admin-ui-enterprise:
name: Build Admin UI Enterprise
needs: [dependencies]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- name: Build
uses: actions/setup-node@v3
with:
node-version: '16.x'
if: steps.node-modules-cache.outputs.cache-hit != 'true'
- run: yarn run build:ui:admin:enterprise
- name: Upload artifact Admin UI Enterprise
uses: actions/upload-artifact@v3
with:
name: admin-ui-ent
path: ./ui/admin/dist/
+14 -14
View File
@@ -6,15 +6,15 @@ jobs:
name: Install dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
- uses: actions/checkout@v3
- uses: actions/cache@v3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16.x'
- run: yarn install
@@ -24,15 +24,15 @@ jobs:
needs: [dependencies]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
- uses: actions/checkout@v3
- uses: actions/cache@v3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16.x'
if: steps.node-modules-cache.outputs.cache-hit != 'true'
@@ -40,19 +40,19 @@ jobs:
lint:
name: Lint
needs: [dependencies]
needs: [dependencies, compliance]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
- uses: actions/checkout@v3
- uses: actions/cache@v3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16.x'
if: steps.node-modules-cache.outputs.cache-hit != 'true'
@@ -60,17 +60,17 @@ jobs:
test:
name: Test
needs: [dependencies]
needs: [lint]
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
- uses: actions/checkout@v3
- uses: actions/cache@v3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16.x'
if: steps.node-modules-cache.outputs.cache-hit != 'true'
+3
View File
@@ -0,0 +1,3 @@
url_license = "https://github.com/hashicorp/boundary-ui/blob/main/LICENSE"
url_project_website = "https://learn.hashicorp.com/tutorials/boundary/getting-started-desktop-app"
url_source_repository = "https://github.com/hashicorp/boundary-ui"
+2 -2
View File
@@ -38,9 +38,9 @@ You will need the following things properly installed on your computer.
* [Git][git]
* [Node.js][node]
* v10–v15
* Supported versions:`v12`, `v14` and `v16`.
* **Apple Silicon Users**: if you experience problems building or running
Boundary UIs, try Node v15.
Boundary UIs, try Node v14.
* [Yarn][yarn] installed globally
* [Google Chrome][chrome]
* [Firefox][firefox]
+6 -3
View File
@@ -2,13 +2,16 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true,
// This is specific babel-config. If grows consider creating a babel config file
requireConfigFile: false,
babelOptions: {
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
},
// end of babel-config
},
plugins: ['ember'],
extends: [
+9 -2
View File
@@ -47,21 +47,28 @@ List of available project commands. `yarn run <command-name>`
| build:development | Builds the dummy app in development mode. |
| build | Builds the dummy app for production. |
| lint | Runs all lint commands. |
| lint:fix | Runs automatic lint fixes for all type of file. |
| lint:hbs | Runs lint for `hbs` template files. |
| lint:hbs:fix | Runs automatic lint fixes for `hbs` template files. |
| lint:js | Lints `js` files. |
| lint:js:fix | Runs automatic lint fixes for `js` files. |
| format | Runs all auto-formatters. |
| format:js | Auto-formats `js` files using Prettier. |
| start | Runs the dummy app local server. |
| test | Runs all tests. |
| test:all | Runs tests across multiple Ember versions with ember-try. |
| test:ember-compatibility | Runs tests across multiple Ember versions with ember-try. |
| precommit | Runs all lint and format. |
| doc:toc | Automatically generates a table of contents for this README file. |
Additional commands in the monorepo package may affect this projects.
## Linting
* `yarn lint:fix`
* `yarn lint:hbs`
* `yarn lint:hbs:fix`
* `yarn lint:js`
* `yarn lint:js --fix`
* `yarn lint:js:fix`
## Formatting
@@ -0,0 +1,16 @@
import ModelAbility from './model';
/**
* Provides abilities for credential store.
*/
export default class CredentialStoreAbility extends ModelAbility {
// =permissions
/**
* Only "known" credential store types may be read.
* @type {boolean}
*/
get canRead() {
return !this.model.isStatic && this.hasAuthorizedAction('read');
}
}
@@ -34,6 +34,12 @@ export default class GeneratedTargetModel extends BaseModel {
})
session_connection_limit;
@attr('string', {
description:
'Optional boolean expression to filter the workers that are allowed to satisfy this request.',
})
worker_filter;
@attr('date', {
description: 'The time this resource was created\nOutput only.',
readOnly: true,
@@ -31,4 +31,9 @@ export default class CredentialStoreModel extends GeneratedCredentialStoreModel
* @type {boolean}
*/
@equal('type', 'vault') isVault;
/**
* @type {boolean}
*/
@equal('type', 'static') isStatic;
}
+7
View File
@@ -23,6 +23,13 @@ export default class RoleModel extends GeneratedRoleModel {
*/
@array('string', { readOnly: true }) grant_strings;
/**
* Convenience for looking up the grant scope, if loaded.
*/
get grantScope() {
return this.store.peekRecord('scope', this.grant_scope_id);
}
// =methods
/**
+4 -4
View File
@@ -13,7 +13,7 @@ class SessionCredential {
/**
*
*/
static Library = class Library {
static Source = class Source {
id;
name;
description;
@@ -42,7 +42,7 @@ class SessionCredential {
// =attributes
rawCredential;
library;
source;
#payloadSecret;
/**
@@ -72,8 +72,8 @@ class SessionCredential {
// =methods
constructor(cred) {
const { id, name, description, type } = cred.credential_library;
this.library = new SessionCredential.Library(id, name, description, type);
const { id, name, description, type } = cred.credential_source;
this.source = new SessionCredential.Source(id, name, description, type);
this.#payloadSecret = cred.secret;
this.rawCredential = cred;
}
+1 -1
View File
@@ -40,7 +40,7 @@ export default class UserModel extends GeneratedUserModel {
* There are many options, so we fallback in order of precedence.
* @type {string}
*/
@computed('email,full_name,login_name,displayName')
@computed('email', 'full_name', 'login_name')
get accountName() {
const { email, full_name, login_name } = this;
return email || full_name || login_name;
+2 -2
View File
@@ -33,7 +33,7 @@ export default class AccountSerializer extends ApplicationSerializer {
* `attributes` entirely on update.
*/
serializeOIDC(snapshot) {
const { isNew } = snapshot?.record;
const { isNew } = snapshot?.record || {};
let serialized = super.serialize(...arguments);
delete serialized.attributes;
if (isNew) {
@@ -70,7 +70,7 @@ export default class AccountSerializer extends ApplicationSerializer {
}
// Change password custom method
if (snapshot?.adapterOptions?.method === 'change-password') {
const { currentPassword, newPassword } = snapshot?.adapterOptions;
const { currentPassword, newPassword } = snapshot?.adapterOptions || {};
serialized = this.serializeForChangePassword(
snapshot,
currentPassword,
+45 -1
View File
@@ -137,7 +137,7 @@ export default class ApplicationSerializer extends RESTSerializer {
}
/**
* In our API, singluar resources are _unrooted_, whereas Ember Data expects
* In our API, singular resources are _unrooted_, whereas Ember Data expects
* them to be rooted under their model name, e.g. `{modelName: {…}}`.
* This method makes this transformation to accommodate Ember Data.
*
@@ -268,4 +268,48 @@ export default class ApplicationSerializer extends RESTSerializer {
});
return hash;
}
/**
* If the API returns an updated response with removed fields, we need to
* explicitly set any read only field that is on the model but wasn't
* returned in the response to `null`.
* This will let ember data know the field was removed, otherwise
* it won't touch the removed field and will use the old value.
*
* @override
* @param {object} store
* @param {object} primaryModelClass
* @param {object} payload
* @param {?string} id
* @param {string} requestType
* @return {object}
*/
normalizeUpdateRecordResponse(
store,
primaryModelClass,
payload,
id,
requestType
) {
const newPayload = copy(payload, true);
primaryModelClass.attributes.forEach((attribute) => {
const {
name,
options: { readOnly },
} = attribute;
if (readOnly && !Object.prototype.hasOwnProperty.call(newPayload, name)) {
newPayload[name] = null;
}
});
return super.normalizeUpdateRecordResponse(
store,
primaryModelClass,
newPayload,
id,
requestType
);
}
}
@@ -0,0 +1 @@
export { default } from 'api/abilities/credential-store';
+4
View File
@@ -1,6 +1,7 @@
import factory from '../generated/factories/account';
import { random, internet } from 'faker';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
export default factory.extend({
authorized_actions: () =>
@@ -11,6 +12,9 @@ export default factory.extend({
'delete',
'set-password',
],
id: () => generateId('acct_'),
attributes() {
switch (this.type) {
case 'password':
+3 -1
View File
@@ -1,6 +1,7 @@
import factory from '../generated/factories/auth-method';
import { trait } from 'ember-cli-mirage';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
const types = ['password', 'oidc'];
@@ -18,7 +19,8 @@ export default factory.extend({
'managed-groups': ['create', 'list'],
};
},
id: (i) => `auth-method-id-${i}`,
id: () => generateId('am_'),
// Cycle through available types
type: (i) => types[i % types.length],
@@ -1,11 +1,12 @@
import factory from '../generated/factories/credential-library';
import { random, system } from 'faker';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
const types = ['vault'];
export default factory.extend({
id: (i) => `credential-library-id-${i}`,
id: () => generateId('cl_'),
type: (i) => types[i % types.length],
authorized_actions: () =>
@@ -2,8 +2,9 @@ import factory from '../generated/factories/credential-store';
import { random, internet, datatype } from 'faker';
import { trait } from 'ember-cli-mirage';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
const types = ['vault'];
const types = ['vault', 'static'];
export default factory.extend({
authorized_actions: () =>
@@ -18,7 +19,7 @@ export default factory.extend({
'credential-libraries': ['create', 'list'],
};
},
id: (i) => `credential-store-id-${i}`,
id: () => generateId('cs_'),
type: (i) => types[i % types.length],
attributes() {
+3 -1
View File
@@ -1,6 +1,7 @@
import factory from '../generated/factories/group';
import { trait } from 'ember-cli-mirage';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
export default factory.extend({
authorized_actions: () =>
@@ -12,7 +13,8 @@ export default factory.extend({
'add-members',
'remove-members',
],
id: (i) => `group-${i}`,
id: () => generateId('g_'),
/**
* Generates some users for the same scope and assigns them to the group
+2 -1
View File
@@ -2,6 +2,7 @@ import factory from '../generated/factories/host-catalog';
import { trait } from 'ember-cli-mirage';
import permissions from '../helpers/permissions';
import { datatype, address, random } from 'faker';
import generateId from '../helpers/id';
const types = ['static', 'plugin'];
// Represents known plugin types, except "foobar" which models the possibility
@@ -11,7 +12,7 @@ const pluginTypes = ['aws', 'azure', 'foobar'];
let pluginTypeCounter = 1;
export default factory.extend({
id: (i) => `host-catalog-id-${i}`,
id: () => generateId('hc_'),
// Cycle through available types
type: (i) => types[i % types.length],
+2 -1
View File
@@ -1,9 +1,10 @@
import factory from '../generated/factories/host-set';
import permissions from '../helpers/permissions';
import { datatype, internet, database } from 'faker';
import generateId from '../helpers/id';
export default factory.extend({
id: (i) => `host-set-id-${i}`,
id: () => generateId('hs_'),
type() {
return this.hostCatalog?.type || factory.attrs.type;
},
+3 -1
View File
@@ -1,9 +1,11 @@
import factory from '../generated/factories/host';
import permissions from '../helpers/permissions';
import { internet, datatype } from 'faker';
import generateId from '../helpers/id';
export default factory.extend({
id: (i) => `host-id-${i}`,
id: () => generateId('h_'),
type() {
return this.hostCatalog?.type || factory.attrs.type;
},
+3 -1
View File
@@ -1,11 +1,11 @@
import factory from '../generated/factories/managed-group';
import { random } from 'faker';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
const types = ['oidc'];
export default factory.extend({
id: (i) => `managed-groups-id-${i}`,
type: (i) => types[i % types.length],
authorized_actions: () =>
@@ -16,6 +16,8 @@ export default factory.extend({
'delete',
],
id: () => generateId('mg_'),
attributes() {
switch (this.type) {
case 'oidc':
+3
View File
@@ -1,6 +1,7 @@
import factory from '../generated/factories/role';
import { trait } from 'ember-cli-mirage';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
export default factory.extend({
authorized_actions: () =>
@@ -19,6 +20,8 @@ export default factory.extend({
'id=*;type=host-catalog;actions=create,read',
],
id: () => generateId('r_'),
/**
* Adds principals to the role.
*/
+2 -9
View File
@@ -1,6 +1,7 @@
import factory from '../generated/factories/scope';
import { trait } from 'ember-cli-mirage';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
export default factory.extend({
type: 'global',
@@ -27,15 +28,7 @@ export default factory.extend({
};
},
/**
* Generates realistic-ish IDs while still being deterministic.
*/
id(i) {
let id = 'tv6fv3yz8p';
if (i % 3) id = 'xk1i4dk50v';
if (i % 2) id = 's9n819zgko';
return `s_${id}${i}`;
},
id: () => generateId('s_'),
withChildren: trait({
afterCreate(record, server) {
+3 -1
View File
@@ -1,13 +1,15 @@
import factory from '../generated/factories/session';
import { trait } from 'ember-cli-mirage';
import { random } from 'faker';
import generateId from '../helpers/id';
const statusStrings = ['pending', 'active', 'canceling', 'terminated'];
export const pickRandomStatusString = () => random.arrayElement(statusStrings);
export default factory.extend({
id: (i) => `session-id-${i}`,
id: () => generateId('ss_'),
status: pickRandomStatusString,
/**
+4
View File
@@ -2,6 +2,7 @@ import factory from '../generated/factories/target';
import { trait } from 'ember-cli-mirage';
import { random, datatype } from 'faker';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
const randomBoolean = (chance = 0.5) => Math.random() < chance;
const hostSetChance = 0.3;
@@ -21,10 +22,13 @@ export default factory.extend({
'remove-credential-sources',
],
id: () => generateId('t_'),
/**
* -1 means "unlimited" and we want to generate these on occasion.
*/
session_connection_limit: () => random.arrayElement([-1, datatype.number()]),
worker_filter: (i) => (i % 2 === 0 ? random.words() : null),
type: (i) => types[i % types.length],
/**
* Generates attributes fields by type.
+2 -1
View File
@@ -1,5 +1,6 @@
import factory from '../generated/factories/user';
import permissions from '../helpers/permissions';
import generateId from '../helpers/id';
export default factory.extend({
authorized_actions: () =>
@@ -11,5 +12,5 @@ export default factory.extend({
'add-accounts',
'remove-accounts',
],
id: (i) => `user-${i}`,
id: () => generateId('u_'),
});
@@ -9,6 +9,7 @@ export default Factory.extend({
name: () => random.words(),
session_max_seconds: () => datatype.number(),
session_connection_limit: () => datatype.number(),
worker_filter: () => random.words(),
description: () => random.words(),
created_time: () => date.recent(),
updated_time: () => date.recent(),
+41
View File
@@ -0,0 +1,41 @@
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
/**
* The Mulberry32 PRNG, JavaScript implementation. This is a seedable PRNG,
* which we need in order to deterministically generate IDs which are stable
* across reloads. Unfortunately, the built-in `Math.random` function
* is not seedable.
*
* Source:
* https://github.com/bryc/code/blob/master/jshash/PRNGs.md#mulberry32
*
* @param {number} a
* @return {number}
*/
function mulberry32(a = 0) {
return function () {
a += 0x6d2b79f5 | 0;
var t = Math.imul(a ^ (a >>> 15), 1 | a);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
const random = mulberry32();
/**
* Generates a random ID string at least 10 characters long with the
* specified prefix.
*
* @param {string} prefix
* @return {string}
*/
export default function (prefix = '') {
let result = '';
for (let i = 0; i < 10; i++) {
result = result.concat(
characters[Math.floor(random() * characters.length)]
);
}
return prefix.concat(result);
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo } from 'ember-cli-mirage';
import { belongsTo } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo } from 'ember-cli-mirage';
import { belongsTo } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+20
View File
@@ -0,0 +1,20 @@
import { Model } from 'ember-cli-mirage';
export default Model.extend({
assignDefaults(defaultAttrs, attrs) {
Object.entries(defaultAttrs).map(([key, value]) => {
if (!attrs[key]) {
attrs[key] = value;
}
});
},
defaultAttrs: () => ({
version: 1,
authorized_actions: ['no-op', 'read', 'update', 'delete'],
created_time: new Date(),
}),
save() {
this.assignDefaults(this.defaultAttrs(), this.attrs);
return Model.prototype.save.apply(this, arguments);
},
});
@@ -1,4 +1,5 @@
import { Model, belongsTo } from 'ember-cli-mirage';
import { belongsTo } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo } from 'ember-cli-mirage';
import { belongsTo } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
import { belongsTo, hasMany } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
import { belongsTo, hasMany } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
import { belongsTo, hasMany } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo } from 'ember-cli-mirage';
import { belongsTo } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo } from 'ember-cli-mirage';
import { belongsTo } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
import { belongsTo, hasMany } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo } from 'ember-cli-mirage';
import { belongsTo } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
import Model from './base';
import { belongsTo, hasMany } from 'ember-cli-mirage';
export default Model.extend({
scope: belongsTo(),
+2 -1
View File
@@ -1,4 +1,5 @@
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
import { belongsTo, hasMany } from 'ember-cli-mirage';
import Model from './base';
export default Model.extend({
scope: belongsTo(),
+12 -12
View File
@@ -66,10 +66,10 @@ export default function initializeMockIPC(server, config) {
session_id: newSession.id,
credentials: [
{
credential_library: {
credential_source: {
id: 'clvlt_4cvscMTl0N',
name: 'Library Name',
description: 'Library Description',
name: 'Source Name',
description: 'Source Description',
credential_store_id: 'csvlt_Q1HFGt7Jpm',
type: 'vault',
},
@@ -78,10 +78,10 @@ export default function initializeMockIPC(server, config) {
},
},
{
credential_library: {
credential_source: {
id: 'clvlt_4cvscMTl0N',
name: 'Library Name',
description: 'Library Description',
name: 'Source Name',
description: 'Source Description',
credential_store_id: 'csvlt_Q1HFGt7Jpm',
type: 'vault',
},
@@ -91,10 +91,10 @@ export default function initializeMockIPC(server, config) {
},
},
{
credential_library: {
credential_source: {
id: 'clvlt_9KWscxpcY7',
name: 'Library Name',
description: 'Library Description',
name: 'Source Name',
description: 'Source Description',
credential_store_id: 'csvlt_Q1HFGt7Jpm',
type: 'vault',
},
@@ -103,10 +103,10 @@ export default function initializeMockIPC(server, config) {
},
},
{
credential_library: {
credential_source: {
id: 'clvlt_9KWscxpcY7',
name: 'Library Name',
description: 'Library Description',
name: 'Source Name',
description: 'Source Description',
credential_store_id: 'csvlt_Q1HFGt7Jpm',
type: 'vault',
},
+7 -5
View File
@@ -16,11 +16,12 @@
"lint:hbs:fix": "ember-template-lint . --fix",
"lint:js": "eslint .",
"lint:js:fix": "eslint . --fix",
"format": "npm run format:js",
"format": "yarn run format:js",
"format:js": "prettier --write '{addon,app,config,stories,tests,mirage}/**/*.js' *.js",
"start": "ember serve",
"test": "ember test",
"test:ember-compatibility": "ember try:each",
"precommit": "yarn lint && yarn format && yarn test",
"doc:toc": "doctoc README.md"
},
"dependencies": {
@@ -33,13 +34,13 @@
"ember-fetch": "^8.1.1"
},
"devDependencies": {
"js-bexpr": "hashicorp/js-bexpr#9b4a4b54d85eba67fdfc0990133d1518d890b1e1",
"@babel/core": "^7.16.5",
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-decorators": "^7.17.8",
"@ember/optional-features": "^2.0.0",
"@ember/test-helpers": "^2.6.0",
"@glimmer/component": "^1.0.4",
"@glimmer/tracking": "^1.0.4",
"babel-eslint": "^10.1.0",
"broccoli-asset-rev": "^3.0.0",
"doctoc": "^2.1.0",
"ember-auto-import": "^1.12.0",
@@ -58,12 +59,13 @@
"ember-resolver": "^8.0.3",
"ember-source": "~3.28.4",
"ember-template-lint": "^3.7.0",
"eslint": "^7.32.0",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-ember": "^10.5.9",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-qunit": "^6.2.0",
"js-bexpr": "hashicorp/js-bexpr#9b4a4b54d85eba67fdfc0990133d1518d890b1e1",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.4.0",
+35
View File
@@ -115,4 +115,39 @@ module('Unit | Model | user', function (hooks) {
'User has empty account_ids by default'
);
});
test('it defaults to null for readonly attributes when response does not have fields', async function (assert) {
assert.expect(3);
this.server.post('/v1/users/123abc:remove-accounts', (schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
account_ids: ['3'],
version: 1,
});
return { id: '123abc', name: 'newName' };
});
const store = this.owner.lookup('service:store');
store.push({
data: {
id: '123abc',
type: 'user',
attributes: {
name: 'user',
description: 'Description',
account_ids: ['3'],
version: 1,
login_name: 'zed',
scope: {
scope_id: 'o_1',
type: 'scope',
},
},
},
});
const model = store.peekRecord('user', '123abc');
await model.removeAccount('3');
assert.equal(model.login_name, null);
assert.equal(model.name, 'newName');
});
});
@@ -211,4 +211,41 @@ module('Unit | Serializer | application', function (hooks) {
},
});
});
test('it normalizes removed fields correctly', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('user');
const user = store.createRecord('user').constructor;
const payload = {
id: '1',
name: 'user 1',
scope: { id: 'o_123' },
};
const normalized = serializer.normalizeUpdateRecordResponse(
store,
user,
payload
);
assert.deepEqual(normalized, {
included: [],
data: {
id: '1',
type: 'user',
attributes: {
authorized_actions: [],
name: 'user 1',
scope: { scope_id: 'o_123' },
account_ids: [],
authorized_collection_actions: null,
created_time: null,
email: null,
full_name: null,
login_name: null,
updated_time: null,
},
relationships: {},
},
});
});
});
@@ -35,6 +35,7 @@ module('Unit | Serializer | target', function (hooks) {
scope_id: 'org_1',
session_max_seconds: 28800,
session_connection_limit: 1,
worker_filter: null,
attributes: {
default_port: 1234,
},
@@ -86,6 +87,38 @@ module('Unit | Serializer | target', function (hooks) {
});
});
test('it serializes the worker_filter attribute if present', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
const record = store.createRecord('target', {
name: 'User',
description: 'Description',
version: 1,
type: 'ssh',
worker_filter: 'worker',
default_port: 1234,
scope: {
scope_id: 'org_1',
},
});
const snapshot = record._createSnapshot();
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
name: 'User',
description: 'Description',
version: 1,
type: 'ssh',
scope_id: 'org_1',
session_max_seconds: 28800,
session_connection_limit: 1,
worker_filter: 'worker',
attributes: {
default_port: 1234,
},
});
});
test('it normalizes records with array fields', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
@@ -189,4 +222,36 @@ module('Unit | Serializer | target', function (hooks) {
},
});
});
test('it normalizes the worker_filter attribute if present', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
const target = store.createRecord('target').constructor;
const payload = {
id: '1',
name: 'Target 1',
worker_filter: 'worker',
};
const normalized = serializer.normalizeSingleResponse(
store,
target,
payload
);
assert.deepEqual(normalized, {
included: [],
data: {
id: '1',
type: 'target',
attributes: {
authorized_actions: [],
name: 'Target 1',
host_sources: [],
application_credential_source_ids: [],
worker_filter: 'worker',
},
relationships: {},
},
});
});
});
+6 -3
View File
@@ -2,13 +2,16 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true,
// This is specific babel-config. If grows consider creating a babel config file
requireConfigFile: false,
babelOptions: {
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
},
// end of babel-config
},
plugins: ['ember'],
extends: [
+3 -1
View File
@@ -34,19 +34,21 @@ List of available project commands. `yarn run <command-name>`
| Command | Description |
| ------- | ----------- |
| lint | Runs all lint commands. |
| lint:fix | Runs automatic lint fixes for all files. |
| lint:js | Lints `js` files. |
| lint:js:fix | Runs automatic lint fixes for `js` files. |
| format | Runs all auto-formatters. |
| format:js | Auto-formats `js` files using Prettier. |
| start | Runs the dummy app local server. |
| test | Runs all tests. |
| test:all | Runs tests across multiple Ember versions with ember-try. |
| precommit | Runs all lint, format and tests. |
| doc:toc | Automatically generates a table of contents for this README file. |
Additional commands in the monorepo package may affect this projects.
## Linting
* `yarn lint:hbs`
* `yarn lint:js`
* `yarn lint:js --fix`
+7 -6
View File
@@ -10,14 +10,14 @@
"scripts": {
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'",
"lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
"lint:hbs:fix": "ember-template-lint . --fix",
"lint:js": "eslint .",
"format": "npm run format:js",
"format:js": "prettier --write '{addon,app,config,stories,tests}/**/*.js' *.js",
"lint:js:fix": "eslint . --fix",
"format": "yarn run format:js",
"format:js": "prettier --write '{addon,app,config,stories,tests}/**/*.js' *.js",
"start": "ember serve",
"test": "ember test",
"test:ember-compatibility": "ember try:each",
"precommit": "yarn lint && yarn format && yarn test",
"doc:toc": "doctoc README.md"
},
"dependencies": {
@@ -27,11 +27,12 @@
"ember-simple-auth": "^4.0.0"
},
"devDependencies": {
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-decorators": "^7.17.8",
"@ember/optional-features": "^2.0.0",
"@ember/test-helpers": "^2.6.0",
"@glimmer/component": "^1.0.4",
"@glimmer/tracking": "^1.0.4",
"babel-eslint": "^10.1.0",
"broccoli-asset-rev": "^3.0.0",
"core": "*",
"doctoc": "^2.1.0",
@@ -51,9 +52,9 @@
"ember-resolver": "^8.0.3",
"ember-source": "~3.28.4",
"ember-template-lint": "^3.7.0",
"eslint": "^7.32.0",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-ember": "^10.5.9",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-qunit": "^6.2.0",
+6 -3
View File
@@ -2,13 +2,16 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true,
// This is specific babel-config. If grows consider creating a babel config file
requireConfigFile: false,
babelOptions: {
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
},
// end of babel-config
},
plugins: ['ember'],
extends: [
+7 -1
View File
@@ -154,11 +154,16 @@ List of available project commands. `yarn run <command-name>`
| build | Builds the dummy app for production. |
| lint | Runs all lint commands. |
| lint:js | Lints `js` files. |
| lint:js:fix | Runs automatic lint fixes for `js` files. |
| lint:hbs | Runs lint for `hbs` template files. |
| lint:hbs:fix | Runs automatic lint fixes for `hbs` template files. |
| format | Runs all auto-formatters. |
| format:js | Auto-formats `js` files using Prettier. |
| format:hbs | Auto-formats `hbs` files using Prettier. |
| start | Runs the dummy app local server. |
| test | Runs all tests. |
| test:all | Runs tests across multiple Ember versions with ember-try. |
| test:ember-compatibility | Runs tests across multiple Ember versions with ember-try. |
| precommit | Runs all lint, format and tests. |
| doc:toc | Automatically generates a table of contents for this README file. |
Additional commands in the monorepo package may affect this projects.
@@ -166,6 +171,7 @@ Additional commands in the monorepo package may affect this projects.
## Linting
* `yarn lint:hbs`
* `yarn lint:hbs --fix`
* `yarn lint:js`
* `yarn lint:js --fix`
@@ -1,3 +1,5 @@
{{!-- //TODO fix the issue and delete disabling the rule --}}
{{!-- template-lint-disable no-passed-in-event-handlers --}}
{{#if @model.type}}
{{component (concat "form/authenticate/" @model.type)
submit=@submit
@@ -0,0 +1,3 @@
<span ...attributes class='image-container'>
{{inline-svg @name}}
</span>
@@ -0,0 +1,18 @@
<Rose::Button
...attributes
@style='inline-link-action'
@iconLeft={{if
this.isLoading
'flight-icons/svg/loading-16'
'flight-icons/svg/reload-16'
}}
class={{if
this.isLoading
'loading-button is-loading'
'loading-button'
}}
@disabled={{this.isLoading}}
{{on 'click' this.toggleRefresh}}
>
{{yield}}
</Rose::Button>
@@ -0,0 +1,20 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { later } from '@ember/runloop';
export default class LoadingButton extends Component {
// =actions
@tracked isLoading = false;
@action
async toggleRefresh() {
this.isLoading = true;
try {
await this.args.onClick();
} catch (e) {
console.error('Error while loading data', e);
}
later(() => (this.isLoading = false), 1000);
}
}
@@ -0,0 +1 @@
{{this.formatted}}
@@ -0,0 +1,103 @@
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
const MILLISECOND = 1;
const SECOND = MILLISECOND * 1000;
const MINUTE = SECOND * 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;
const MONTH = DAY * 31;
const YEAR = MONTH * 12;
// common time intervals in milliseconds
const unitMappings = [
{
unit: 'second',
value: SECOND,
},
{
unit: 'minute',
value: MINUTE,
},
{
unit: 'hour',
value: HOUR,
},
{
unit: 'day',
value: DAY,
},
{
unit: 'month',
value: MONTH,
},
{
unit: 'year',
value: YEAR,
},
];
export default class RelativeDatetimeLiveComponent extends Component {
// =services
@service clockTick;
@service intl;
// =properties
/**
* The difference in milliseconds between the date argument and the
* current time.
* @type {number}
*/
get delta() {
return this.args.date.valueOf() - this.clockTick.now;
}
/**
* The greatest meaningful unit is the unit which delta is equal to or
* greater than. For example, the unit of a delta equivalent of 59 seconds is
* 'second' while 60 seconds is 'minute', 36 hours is 'day', etc.
* @type {object}
*/
get greatestMeaningfulUnit() {
return unitMappings.reduce((currentValue, previousValue) => {
return Math.abs(this.delta) >= previousValue.value
? previousValue
: currentValue;
}, unitMappings[0]);
}
/**
* The delta value scaled to the greatest meaningful unit. For example, if
* the delta is 1000 ms, the scaled value is 1, which corresponds to
* a GMU of 'second'. A delta of 60000 ms is also 1, corresponding to a GMU
* of 'minute'.
* @type {number}
*/
get scaledDelta() {
if (this.delta < 0) {
return Math.ceil(this.delta / this.greatestMeaningfulUnit.value);
}
return Math.floor(this.delta / this.greatestMeaningfulUnit.value);
}
/**
* A string representation of the greatest meaningful unit.
* @type {string}
*/
get unit() {
return this.greatestMeaningfulUnit.unit;
}
/**
* A localizd relative datetime. E.g. "30 seconds ago".
* @type {string}
*/
get formatted() {
return this.intl.formatRelative(this.scaledDelta, {
unit: this.unit,
numeric: 'auto',
});
}
}
@@ -0,0 +1,9 @@
{{#if this.lastRefreshed}}
<Rose::Toolbar::Info>
<RelativeDatetimeLive @date={{this.lastRefreshed}} />
</Rose::Toolbar::Info>
{{/if}}
<LoadingButton @onClick={{this.onClick}}>
{{t 'actions.refresh'}}
</LoadingButton>
@@ -0,0 +1,20 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class ToolbarRefresherComponent extends Component {
// =properties
@tracked lastRefreshed = null;
// =methods
/**
* Executes the click handler argument and trackes the time it completed.
*/
@action
async onClick() {
await this.args.onClick();
this.lastRefreshed = new Date();
}
}
+78
View File
@@ -0,0 +1,78 @@
import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { getOwner } from '@ember/application';
import { next } from '@ember/runloop';
export default class ClockTickService extends Service {
// =attributes
/**
* The current datetime. This is updated once every `interval` while the
* service is running (1s by default).
* @type {number}
*/
@tracked now = Date.now();
/**
* The frequency to update `now`, in milliseconds.
* @type {number}
*/
frequency = 1000;
/**
* The timer interval ID
*/
#timer;
/**
* This service is enabled only in non-test environments.
* @type {boolean}
*/
get enabled() {
const config = getOwner(this).resolveRegistration('config:environment');
return config.environment !== 'test';
}
// =methods
/**
* Starts the timer, if enabled.
*/
constructor() {
super(...arguments);
if (this.enabled) this._start();
}
/**
* Stops the timer.
*/
willDestroy() {
super.willDestroy(...arguments);
this._stop();
}
/**
* Sets up the timer interval, calling `_tick()` every
* `frequency` milliseconds.
*/
_start() {
const self = this;
this.#timer = setInterval(function () {
self._tick();
}, this.frequency);
}
/**
* Clears the timer interval.
*/
_stop() {
clearInterval(this.#timer);
}
/**
* Updates the value of `now` within the next runloop.
*/
_tick() {
next(() => (this.now = Date.now()));
}
}
+1
View File
@@ -0,0 +1 @@
export { default } from 'core/components/image';
@@ -0,0 +1 @@
export { default } from 'core/components/loading-button';
@@ -0,0 +1 @@
export { default } from 'core/components/relative-datetime-live';
@@ -0,0 +1 @@
export { default } from 'core/components/toolbar-refresher';
+1
View File
@@ -0,0 +1 @@
export { default } from 'core/services/clock-tick';
+9 -5
View File
@@ -17,14 +17,17 @@
"build": "ember build --environment=production",
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'",
"lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
"lint:hbs": "ember-template-lint .",
"lint:hbs:fix": "ember-template-lint . --fix",
"lint:js": "eslint .",
"format": "npm run format:js",
"format:js": "prettier --write '{addon,app,config,stories,tests}/**/*.js' *.js",
"lint:js:fix": "eslint . --fix",
"format": "npm-run-all format:*",
"format:js": "prettier --write '{addon,app,config,stories,tests}/**/*.js' *.js",
"format:hbs": "prettier --write '{addon,app,tests}/**/*.hbs'",
"start": "ember serve",
"test": "ember test",
"test:ember-compatibility": "ember try:each",
"precommit": "yarn lint && yarn format && yarn test",
"doc:toc": "doctoc README.md"
},
"dependencies": {
@@ -41,11 +44,12 @@
"rose": "*"
},
"devDependencies": {
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-decorators": "^7.17.8",
"@ember/optional-features": "^2.0.0",
"@ember/test-helpers": "^2.6.0",
"@glimmer/component": "^1.0.4",
"@glimmer/tracking": "^1.0.4",
"babel-eslint": "^10.1.0",
"broccoli-asset-rev": "^3.0.0",
"doctoc": "^2.1.0",
"ember-auto-import": "^1.12.0",
@@ -64,9 +68,9 @@
"ember-resolver": "^8.0.3",
"ember-source": "~3.28.4",
"ember-template-lint": "^3.7.0",
"eslint": "^7.32.0",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-ember": "^10.5.4",
"eslint-plugin-ember": "^10.5.9",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-qunit": "^6.2.0",
@@ -0,0 +1,12 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 8C0 4.22876 0 2.34315 1.17157 1.17157C2.34315 0 4.22876 0 8 0H24C27.7712 0 29.6569 0 30.8284 1.17157C32 2.34315 32 4.22876 32 8V24C32 27.7712 32 29.6569 30.8284 30.8284C29.6569 32 27.7712 32 24 32H8C4.22876 32 2.34315 32 1.17157 30.8284C0 29.6569 0 27.7712 0 24V8Z" fill="url(#paint0_linear_4389_56864)"/>
<path d="M10.9261 25.03V23.6294H13.8501V22.7694H12.4249V21.3688H19.0838L15.9878 16.0123L19.0838 10.6557H12.2529V18.0763H8.5918V6.96997H21.2215L23.3347 10.6311L20.2387 16.0123L23.4084 21.4917L21.3444 25.03H10.9261Z" fill="white"/>
<path d="M11.4914 21.3688H10.0908V22.7694H11.4914V21.3688Z" fill="white"/>
<path d="M9.99237 23.6294H8.5918V25.03H9.99237V23.6294Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_4389_56864" x1="16" y1="0" x2="16" y2="32" gradientUnits="userSpaceOnUse">
<stop stop-color="#F66F74"/>
<stop offset="1" stop-color="#F34D52"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1009 B

+123
View File
@@ -0,0 +1,123 @@
<svg width="482" height="209" viewBox="0 0 482 209" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_dd_4385_55671)">
<rect x="41" y="12" width="150" height="52" rx="2" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58 33.25C58 32.0074 59.0074 31 60.25 31H66.75C67.9926 31 69 32.0074 69 33.25V35.3622L71.0506 36.8147C71.6461 37.2365 72.0001 37.921 72.0001 38.6507L72.0001 43.7501C72.0001 44.4404 71.4404 45.0001 70.7501 45.0001H68.2501C68.0421 45.0001 67.854 44.9154 67.7181 44.7788C67.5833 44.6432 67.5 44.4563 67.5 44.25V33.25C67.5 32.8358 67.1642 32.5 66.75 32.5H60.25C59.8358 32.5 59.5 32.8358 59.5 33.25V44.25C59.5 44.6642 59.1642 45 58.75 45C58.3358 45 58 44.6642 58 44.25V33.25ZM69 43.5001V37.2004L70.1836 38.0387C70.3821 38.1793 70.5001 38.4075 70.5001 38.6507L70.5001 43.5001H69Z" fill="#BAC1CC"/>
<path d="M61.75 40.5498C61.3634 40.5498 61.05 40.8632 61.05 41.2498V44.2498C61.05 44.6364 61.3634 44.9498 61.75 44.9498C62.1366 44.9498 62.45 44.6364 62.45 44.2498V41.9498H64.55V44.2498C64.55 44.6364 64.8634 44.9498 65.25 44.9498C65.6366 44.9498 65.95 44.6364 65.95 44.2498V41.2498C65.95 40.8632 65.6366 40.5498 65.25 40.5498H61.75Z" fill="#BAC1CC"/>
<path d="M61.25 34.75C61.25 34.3358 61.5858 34 62 34H62.25C62.6642 34 63 34.3358 63 34.75C63 35.1642 62.6642 35.5 62.25 35.5H62C61.5858 35.5 61.25 35.1642 61.25 34.75Z" fill="#BAC1CC"/>
<path d="M64.75 34C64.3358 34 64 34.3358 64 34.75C64 35.1642 64.3358 35.5 64.75 35.5H65C65.4142 35.5 65.75 35.1642 65.75 34.75C65.75 34.3358 65.4142 34 65 34H64.75Z" fill="#BAC1CC"/>
<path d="M61.25 36.75C61.25 36.3358 61.5858 36 62 36H62.25C62.6642 36 63 36.3358 63 36.75C63 37.1642 62.6642 37.5 62.25 37.5H62C61.5858 37.5 61.25 37.1642 61.25 36.75Z" fill="#BAC1CC"/>
<path d="M64.75 36C64.3358 36 64 36.3358 64 36.75C64 37.1642 64.3358 37.5 64.75 37.5H65C65.4142 37.5 65.75 37.1642 65.75 36.75C65.75 36.3358 65.4142 36 65 36H64.75Z" fill="#BAC1CC"/>
<path d="M61.25 38.75C61.25 38.3358 61.5858 38 62 38H62.25C62.6642 38 63 38.3358 63 38.75C63 39.1642 62.6642 39.5 62.25 39.5H62C61.5858 39.5 61.25 39.1642 61.25 38.75Z" fill="#BAC1CC"/>
<path d="M64.75 38C64.3358 38 64 38.3358 64 38.75C64 39.1642 64.3358 39.5 64.75 39.5H65C65.4142 39.5 65.75 39.1642 65.75 38.75C65.75 38.3358 65.4142 38 65 38H64.75Z" fill="#BAC1CC"/>
<path d="M87.25 32.4453C83.9766 32.4453 81.9141 34.7188 81.9141 38.3594C81.9141 41.9922 83.9453 44.2812 87.25 44.2812C90.5391 44.2812 92.5781 41.9922 92.5781 38.3594C92.5781 34.7188 90.5312 32.4453 87.25 32.4453ZM87.25 34.1875C89.25 34.1875 90.5234 35.8047 90.5234 38.3594C90.5234 40.8984 89.2578 42.5391 87.25 42.5391C85.2188 42.5391 83.9766 40.8984 83.9766 38.3594C83.9766 35.8047 85.25 34.1875 87.25 34.1875ZM94.4175 44H96.355V39.0391C96.355 37.8359 97.23 37.0547 98.4878 37.0547C98.8159 37.0547 99.3316 37.1094 99.48 37.1641V35.3984C99.3003 35.3516 98.9566 35.3203 98.6753 35.3203C97.5737 35.3203 96.6519 35.9453 96.4175 36.7891H96.2847V35.4609H94.4175V44ZM104.257 47.25C106.749 47.25 108.327 46.0078 108.327 44.0469V35.4609H106.46V36.8281H106.327C105.858 35.8984 104.843 35.3203 103.679 35.3203C101.499 35.3203 100.147 37.0234 100.147 39.6406C100.147 42.2031 101.491 43.875 103.647 43.875C104.835 43.875 105.765 43.375 106.257 42.4531H106.39V44.0781C106.39 45.1641 105.616 45.8047 104.288 45.8047C103.226 45.8047 102.538 45.4219 102.413 44.8203H100.468C100.624 46.2891 102.062 47.25 104.257 47.25ZM104.257 42.3359C102.905 42.3359 102.14 41.2891 102.14 39.6328C102.14 37.9844 102.905 36.9375 104.257 36.9375C105.601 36.9375 106.421 37.9844 106.421 39.6406C106.421 41.2891 105.608 42.3359 104.257 42.3359Z" fill="#BAC1CC"/>
<rect x="40.5" y="11.5" width="151" height="53" rx="2.5" stroke="#BAC1CC"/>
</g>
<path d="M59.5 76.75C59.5 76.3358 59.8358 76 60.25 76C60.6642 76 61 76.3358 61 76.75V81.25C61 81.7141 61.1844 82.1592 61.5126 82.4874C61.8408 82.8156 62.2859 83 62.75 83H68.4393L66.2197 80.7803C65.9268 80.4874 65.9268 80.0126 66.2197 79.7197C66.5126 79.4268 66.9874 79.4268 67.2803 79.7197L70.7803 83.2197C71.0732 83.5126 71.0732 83.9874 70.7803 84.2803L67.2803 87.7803C66.9874 88.0732 66.5126 88.0732 66.2197 87.7803C65.9268 87.4874 65.9268 87.0126 66.2197 86.7197L68.4393 84.5H62.75C61.888 84.5 61.0614 84.1576 60.4519 83.5481C59.8424 82.9386 59.5 82.112 59.5 81.25V76.75Z" fill="#6F7682"/>
<g filter="url(#filter1_dd_4385_55671)">
<rect x="85" y="56" width="150" height="52" rx="2" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M103.25 75C102.56 75 102 75.5596 102 76.25V79.75C102 80.4404 102.56 81 103.25 81H106.75C107.44 81 108 80.4404 108 79.75V76.25C108 75.5596 107.44 75 106.75 75H103.25ZM103.5 79.5V76.5H106.5V79.5H103.5Z" fill="#BAC1CC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M111.25 75C110.56 75 110 75.5596 110 76.25V79.75C110 80.4404 110.56 81 111.25 81H114.75C115.44 81 116 80.4404 116 79.75V76.25C116 75.5596 115.44 75 114.75 75H111.25ZM111.5 79.5V76.5H114.5V79.5H111.5Z" fill="#BAC1CC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M110 84.25C110 83.5596 110.56 83 111.25 83H114.75C115.44 83 116 83.5596 116 84.25V87.75C116 88.4404 115.44 89 114.75 89H111.25C110.56 89 110 88.4404 110 87.75V84.25ZM111.5 84.5V87.5H114.5V84.5H111.5Z" fill="#BAC1CC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M103.25 83C102.56 83 102 83.5596 102 84.25V87.75C102 88.4404 102.56 89 103.25 89H106.75C107.44 89 108 88.4404 108 87.75V84.25C108 83.5596 107.44 83 106.75 83H103.25ZM103.5 87.5V84.5H106.5V87.5H103.5Z" fill="#BAC1CC"/>
<path d="M126.391 76.7266V88H128.406V84.2734H130.852C133.133 84.2734 134.727 82.75 134.727 80.5234C134.727 78.2578 133.188 76.7266 130.938 76.7266H126.391ZM128.406 78.375H130.406C131.859 78.375 132.68 79.125 132.68 80.5234C132.68 81.8828 131.836 82.6484 130.398 82.6484H128.406V78.375ZM136.48 88H138.417V83.0391C138.417 81.8359 139.292 81.0547 140.55 81.0547C140.878 81.0547 141.394 81.1094 141.542 81.1641V79.3984C141.363 79.3516 141.019 79.3203 140.738 79.3203C139.636 79.3203 138.714 79.9453 138.48 80.7891H138.347V79.4609H136.48V88ZM146.335 88.1719C148.89 88.1719 150.444 86.5 150.444 83.7266C150.444 80.9688 148.882 79.2969 146.335 79.2969C143.796 79.2969 142.226 80.9766 142.226 83.7266C142.226 86.5 143.772 88.1719 146.335 88.1719ZM146.335 86.5859C144.983 86.5859 144.21 85.5391 144.21 83.7344C144.21 81.9297 144.983 80.8828 146.335 80.8828C147.679 80.8828 148.452 81.9297 148.452 83.7344C148.452 85.5391 147.687 86.5859 146.335 86.5859ZM153.128 78.0312C153.76 78.0312 154.284 77.5234 154.284 76.8828C154.284 76.25 153.76 75.7344 153.128 75.7344C152.487 75.7344 151.963 76.25 151.963 76.8828C151.963 77.5234 152.487 78.0312 153.128 78.0312ZM154.081 79.4609H152.151V88.3047C152.151 89.0938 151.846 89.4141 150.987 89.4141C150.948 89.4141 150.76 89.4141 150.737 89.4062V90.8984C150.792 90.9062 151.104 90.9141 151.206 90.9141C153.12 90.9141 154.081 90.0781 154.081 88.3281V79.4609ZM161.787 85.6641C161.506 86.3047 160.842 86.6641 159.881 86.6641C158.608 86.6641 157.787 85.7578 157.74 84.3125V84.2109H163.709V83.5938C163.709 80.9141 162.248 79.2969 159.811 79.2969C157.334 79.2969 155.795 81.0234 155.795 83.7656C155.795 86.5 157.311 88.1719 159.826 88.1719C161.842 88.1719 163.272 87.2031 163.623 85.6641H161.787ZM159.803 80.8047C160.967 80.8047 161.733 81.625 161.772 82.9219H157.748C157.834 81.6406 158.647 80.8047 159.803 80.8047ZM172.767 82.3125C172.564 80.5469 171.236 79.2969 169.041 79.2969C166.47 79.2969 164.963 80.9453 164.963 83.7109C164.963 86.5078 166.478 88.1719 169.048 88.1719C171.213 88.1719 172.556 86.9688 172.767 85.2031H170.923C170.72 86.1016 170.048 86.5781 169.041 86.5781C167.72 86.5781 166.923 85.5234 166.923 83.7109C166.923 81.9297 167.713 80.8828 169.041 80.8828C170.103 80.8828 170.744 81.4844 170.923 82.3125H172.767ZM175.075 77.3672V79.5156H173.724V81.0234H175.075V85.7344C175.075 87.3828 175.857 88.0391 177.818 88.0391C178.193 88.0391 178.552 88.0078 178.833 87.9531V86.4688C178.599 86.4922 178.45 86.5078 178.177 86.5078C177.364 86.5078 177.005 86.125 177.005 85.2734V81.0234H178.833V79.5156H177.005V77.3672H175.075Z" fill="#BAC1CC"/>
<rect x="84.5" y="55.5" width="151" height="53" rx="2.5" stroke="#BAC1CC"/>
</g>
<path d="M103.5 120.75C103.5 120.336 103.836 120 104.25 120C104.664 120 105 120.336 105 120.75V125.25C105 125.714 105.184 126.159 105.513 126.487C105.841 126.816 106.286 127 106.75 127H112.439L110.22 124.78C109.927 124.487 109.927 124.013 110.22 123.72C110.513 123.427 110.987 123.427 111.28 123.72L114.78 127.22C115.073 127.513 115.073 127.987 114.78 128.28L111.28 131.78C110.987 132.073 110.513 132.073 110.22 131.78C109.927 131.487 109.927 131.013 110.22 130.72L112.439 128.5H106.75C105.888 128.5 105.061 128.158 104.452 127.548C103.842 126.939 103.5 126.112 103.5 125.25V120.75Z" fill="#6F7682"/>
<g filter="url(#filter2_dd_4385_55671)">
<rect x="129" y="100" width="150" height="52" rx="2" fill="white"/>
<path d="M148.05 122.75C148.05 122.363 148.363 122.05 148.75 122.05H152.25C152.637 122.05 152.95 122.363 152.95 122.75C152.95 123.137 152.637 123.45 152.25 123.45H148.75C148.363 123.45 148.05 123.137 148.05 122.75Z" fill="#BAC1CC"/>
<path d="M148.75 125.05C148.363 125.05 148.05 125.363 148.05 125.75C148.05 126.137 148.363 126.45 148.75 126.45H151.25C151.637 126.45 151.95 126.137 151.95 125.75C151.95 125.363 151.637 125.05 151.25 125.05H148.75Z" fill="#BAC1CC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M145 121.25C145 120.007 146.007 119 147.25 119H153.75C154.633 119 155.398 119.509 155.766 120.25H156.75C157.448 120.25 158.051 120.659 158.332 121.25H159.25C160.216 121.25 161 122.034 161 123V129C161 129.966 160.216 130.75 159.25 130.75H158.332C158.051 131.341 157.448 131.75 156.75 131.75H155.766C155.398 132.491 154.633 133 153.75 133H147.25C146.007 133 145 131.993 145 130.75V121.25ZM158.5 129.25H159.25C159.388 129.25 159.5 129.138 159.5 129V123C159.5 122.862 159.388 122.75 159.25 122.75H158.5V129.25ZM156 130.25V121.75H156.75C156.888 121.75 157 121.862 157 122V130C157 130.138 156.888 130.25 156.75 130.25H156ZM147.25 120.5C146.836 120.5 146.5 120.836 146.5 121.25V130.75C146.5 131.164 146.836 131.5 147.25 131.5H153.75C154.164 131.5 154.5 131.164 154.5 130.75V121.25C154.5 120.836 154.164 120.5 153.75 120.5H147.25Z" fill="#BAC1CC"/>
<path d="M179.898 132V120.727H177.891V125.414H172.406V120.727H170.391V132H172.406V127.109H177.891V132H179.898ZM185.902 132.172C188.457 132.172 190.011 130.5 190.011 127.727C190.011 124.969 188.449 123.297 185.902 123.297C183.363 123.297 181.792 124.977 181.792 127.727C181.792 130.5 183.339 132.172 185.902 132.172ZM185.902 130.586C184.55 130.586 183.777 129.539 183.777 127.734C183.777 125.93 184.55 124.883 185.902 124.883C187.246 124.883 188.019 125.93 188.019 127.734C188.019 129.539 187.253 130.586 185.902 130.586ZM191.499 125.898C191.499 127.18 192.272 127.93 193.913 128.305L195.429 128.656C196.241 128.844 196.608 129.156 196.608 129.641C196.608 130.289 195.929 130.734 194.952 130.734C193.983 130.734 193.382 130.344 193.194 129.711H191.28C191.429 131.25 192.772 132.172 194.905 132.172C197.038 132.172 198.546 131.086 198.546 129.453C198.546 128.195 197.788 127.5 196.155 127.125L194.647 126.789C193.788 126.586 193.382 126.281 193.382 125.797C193.382 125.164 194.046 124.734 194.929 124.734C195.835 124.734 196.405 125.125 196.546 125.727H198.366C198.226 124.188 196.952 123.297 194.921 123.297C192.905 123.297 191.499 124.367 191.499 125.898ZM200.792 121.367V123.516H199.44V125.023H200.792V129.734C200.792 131.383 201.573 132.039 203.534 132.039C203.909 132.039 204.268 132.008 204.549 131.953V130.469C204.315 130.492 204.167 130.508 203.893 130.508C203.081 130.508 202.721 130.125 202.721 129.273V125.023H204.549V123.516H202.721V121.367H200.792ZM210.017 125.898C210.017 127.18 210.791 127.93 212.431 128.305L213.947 128.656C214.759 128.844 215.127 129.156 215.127 129.641C215.127 130.289 214.447 130.734 213.47 130.734C212.502 130.734 211.9 130.344 211.713 129.711H209.798C209.947 131.25 211.291 132.172 213.423 132.172C215.556 132.172 217.064 131.086 217.064 129.453C217.064 128.195 216.306 127.5 214.673 127.125L213.166 126.789C212.306 126.586 211.9 126.281 211.9 125.797C211.9 125.164 212.564 124.734 213.447 124.734C214.353 124.734 214.923 125.125 215.064 125.727H216.884C216.744 124.188 215.47 123.297 213.439 123.297C211.423 123.297 210.017 124.367 210.017 125.898ZM224.325 129.664C224.044 130.305 223.38 130.664 222.419 130.664C221.146 130.664 220.325 129.758 220.278 128.312V128.211H226.247V127.594C226.247 124.914 224.786 123.297 222.349 123.297C219.872 123.297 218.333 125.023 218.333 127.766C218.333 130.5 219.849 132.172 222.364 132.172C224.38 132.172 225.81 131.203 226.161 129.664H224.325ZM222.341 124.805C223.505 124.805 224.271 125.625 224.31 126.922H220.286C220.372 125.641 221.185 124.805 222.341 124.805ZM228.54 121.367V123.516H227.188V125.023H228.54V129.734C228.54 131.383 229.321 132.039 231.282 132.039C231.657 132.039 232.016 132.008 232.298 131.953V130.469C232.063 130.492 231.915 130.508 231.641 130.508C230.829 130.508 230.469 130.125 230.469 129.273V125.023H232.298V123.516H230.469V121.367H228.54Z" fill="#BAC1CC"/>
<rect x="128.5" y="99.5" width="151" height="53" rx="2.5" stroke="#BAC1CC"/>
</g>
<path d="M147.5 164.75C147.5 164.336 147.836 164 148.25 164C148.664 164 149 164.336 149 164.75V169.25C149 169.714 149.184 170.159 149.513 170.487C149.841 170.816 150.286 171 150.75 171H156.439L154.22 168.78C153.927 168.487 153.927 168.013 154.22 167.72C154.513 167.427 154.987 167.427 155.28 167.72L158.78 171.22C159.073 171.513 159.073 171.987 158.78 172.28L155.28 175.78C154.987 176.073 154.513 176.073 154.22 175.78C153.927 175.487 153.927 175.013 154.22 174.72L156.439 172.5H150.75C149.888 172.5 149.061 172.158 148.452 171.548C147.842 170.939 147.5 170.112 147.5 169.25V164.75Z" fill="#6F7682"/>
<g filter="url(#filter3_dd_4385_55671)">
<rect x="173" y="144" width="150" height="52" rx="2" fill="white"/>
<path d="M197 164.5C195.104 164.5 193.432 165.458 192.442 166.921C192.21 167.263 191.744 167.353 191.401 167.121C191.058 166.889 190.968 166.422 191.2 166.079C192.457 164.223 194.586 163 197 163C200.866 163 204 166.134 204 170C204 173.866 200.866 177 197 177C194.586 177 192.457 175.777 191.2 173.921C190.968 173.578 191.058 173.111 191.401 172.879C191.744 172.647 192.21 172.737 192.442 173.079C193.432 174.542 195.104 175.5 197 175.5C200.038 175.5 202.5 173.038 202.5 170C202.5 166.962 200.038 164.5 197 164.5Z" fill="black"/>
<path d="M196.245 166.695C195.939 166.974 195.916 167.448 196.195 167.755L197.555 169.25H190.75C190.336 169.25 190 169.586 190 170C190 170.414 190.336 170.75 190.75 170.75H197.555L196.195 172.246C195.916 172.552 195.939 173.026 196.245 173.305C196.552 173.584 197.026 173.561 197.305 173.255L199.805 170.505C200.065 170.218 200.065 169.782 199.805 169.496L197.305 166.746C197.026 166.439 196.552 166.416 196.245 166.695Z" fill="black"/>
<path d="M219.523 176V171.555L223.477 164.727H221.266L218.586 169.562H218.453L215.766 164.727H213.555L217.508 171.555V176H219.523ZM227.183 176.172C229.738 176.172 231.292 174.5 231.292 171.727C231.292 168.969 229.73 167.297 227.183 167.297C224.644 167.297 223.074 168.977 223.074 171.727C223.074 174.5 224.621 176.172 227.183 176.172ZM227.183 174.586C225.832 174.586 225.058 173.539 225.058 171.734C225.058 169.93 225.832 168.883 227.183 168.883C228.527 168.883 229.3 169.93 229.3 171.734C229.3 173.539 228.535 174.586 227.183 174.586ZM240.413 167.461H238.476V172.438C238.476 173.727 237.788 174.508 236.53 174.508C235.374 174.508 234.835 173.867 234.835 172.539V167.461H232.897V173.008C232.897 175.008 233.991 176.172 235.858 176.172C237.163 176.172 237.999 175.617 238.413 174.641H238.546V176H240.413V167.461ZM242.518 176H244.456V171.039C244.456 169.836 245.331 169.055 246.588 169.055C246.917 169.055 247.432 169.109 247.581 169.164V167.398C247.401 167.352 247.057 167.32 246.776 167.32C245.674 167.32 244.753 167.945 244.518 168.789H244.385V167.461H242.518V176ZM252.978 176H254.916V171.039C254.916 169.789 255.627 168.953 256.9 168.953C258.025 168.953 258.619 169.625 258.619 170.945V176H260.556V170.492C260.556 168.461 259.447 167.305 257.619 167.305C256.345 167.305 255.431 167.883 255.025 168.844H254.884V164.156H252.978V176ZM266.271 176.172C268.825 176.172 270.38 174.5 270.38 171.727C270.38 168.969 268.818 167.297 266.271 167.297C263.732 167.297 262.161 168.977 262.161 171.727C262.161 174.5 263.708 176.172 266.271 176.172ZM266.271 174.586C264.919 174.586 264.146 173.539 264.146 171.734C264.146 169.93 264.919 168.883 266.271 168.883C267.614 168.883 268.388 169.93 268.388 171.734C268.388 173.539 267.622 174.586 266.271 174.586ZM271.868 169.898C271.868 171.18 272.641 171.93 274.282 172.305L275.798 172.656C276.61 172.844 276.977 173.156 276.977 173.641C276.977 174.289 276.298 174.734 275.321 174.734C274.352 174.734 273.751 174.344 273.563 173.711H271.649C271.798 175.25 273.141 176.172 275.274 176.172C277.407 176.172 278.915 175.086 278.915 173.453C278.915 172.195 278.157 171.5 276.524 171.125L275.016 170.789C274.157 170.586 273.751 170.281 273.751 169.797C273.751 169.164 274.415 168.734 275.298 168.734C276.204 168.734 276.774 169.125 276.915 169.727H278.735C278.594 168.188 277.321 167.297 275.29 167.297C273.274 167.297 271.868 168.367 271.868 169.898ZM281.16 165.367V167.516H279.809V169.023H281.16V173.734C281.16 175.383 281.942 176.039 283.902 176.039C284.277 176.039 284.637 176.008 284.918 175.953V174.469C284.684 174.492 284.535 174.508 284.262 174.508C283.449 174.508 283.09 174.125 283.09 173.273V169.023H284.918V167.516H283.09V165.367H281.16Z" fill="black"/>
<rect x="172.5" y="143.5" width="151" height="53" rx="2.5" stroke="#BAC1CC"/>
</g>
<line x1="323" y1="169.5" x2="335" y2="169.5" stroke="#BAC1CC"/>
<g filter="url(#filter4_dd_4385_55671)">
<rect x="335" y="144" width="106" height="52" rx="2" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M359 168C357.895 168 357 168.895 357 170C357 171.105 357.895 172 359 172C360.105 172 361 171.105 361 170C361 168.895 360.105 168 359 168ZM358.5 170C358.5 169.724 358.724 169.5 359 169.5C359.276 169.5 359.5 169.724 359.5 170C359.5 170.276 359.276 170.5 359 170.5C358.724 170.5 358.5 170.276 358.5 170Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M354 170C354 167.239 356.239 165 359 165C361.761 165 364 167.239 364 170C364 172.761 361.761 175 359 175C356.239 175 354 172.761 354 170ZM359 166.5C357.067 166.5 355.5 168.067 355.5 170C355.5 171.933 357.067 173.5 359 173.5C360.933 173.5 362.5 171.933 362.5 170C362.5 168.067 360.933 166.5 359 166.5Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M351 170C351 165.582 354.582 162 359 162C363.418 162 367 165.582 367 170C367 174.418 363.418 178 359 178C354.582 178 351 174.418 351 170ZM359 163.5C355.41 163.5 352.5 166.41 352.5 170C352.5 173.59 355.41 176.5 359 176.5C362.59 176.5 365.5 173.59 365.5 170C365.5 166.41 362.59 163.5 359 163.5Z" fill="black"/>
<path d="M381.211 176V166.422H384.688V164.727H375.727V166.422H379.195V176H381.211ZM387.128 176.141C388.246 176.141 389.183 175.656 389.66 174.828H389.792V176H391.66V170.164C391.66 168.359 390.425 167.297 388.23 167.297C386.199 167.297 384.785 168.25 384.628 169.742H386.457C386.636 169.156 387.246 168.836 388.136 168.836C389.183 168.836 389.746 169.312 389.746 170.164V170.898L387.542 171.031C385.464 171.148 384.3 172.047 384.3 173.578C384.3 175.141 385.48 176.141 387.128 176.141ZM387.699 174.648C386.839 174.648 386.222 174.219 386.222 173.484C386.222 172.773 386.73 172.375 387.816 172.305L389.746 172.172V172.867C389.746 173.883 388.871 174.648 387.699 174.648ZM393.726 176H395.663V171.039C395.663 169.836 396.538 169.055 397.796 169.055C398.124 169.055 398.64 169.109 398.788 169.164V167.398C398.608 167.352 398.265 167.32 397.983 167.32C396.882 167.32 395.96 167.945 395.726 168.789H395.593V167.461H393.726V176ZM403.565 179.25C406.057 179.25 407.635 178.008 407.635 176.047V167.461H405.768V168.828H405.635C405.167 167.898 404.151 167.32 402.987 167.32C400.807 167.32 399.456 169.023 399.456 171.641C399.456 174.203 400.799 175.875 402.956 175.875C404.143 175.875 405.073 175.375 405.565 174.453H405.698V176.078C405.698 177.164 404.924 177.805 403.596 177.805C402.534 177.805 401.846 177.422 401.721 176.82H399.776C399.932 178.289 401.37 179.25 403.565 179.25ZM403.565 174.336C402.213 174.336 401.448 173.289 401.448 171.633C401.448 169.984 402.213 168.938 403.565 168.938C404.909 168.938 405.729 169.984 405.729 171.641C405.729 173.289 404.917 174.336 403.565 174.336ZM415.318 173.664C415.037 174.305 414.373 174.664 413.412 174.664C412.139 174.664 411.318 173.758 411.272 172.312V172.211H417.24V171.594C417.24 168.914 415.779 167.297 413.342 167.297C410.865 167.297 409.326 169.023 409.326 171.766C409.326 174.5 410.842 176.172 413.357 176.172C415.373 176.172 416.803 175.203 417.154 173.664H415.318ZM413.334 168.805C414.498 168.805 415.264 169.625 415.303 170.922H411.279C411.365 169.641 412.178 168.805 413.334 168.805ZM419.533 165.367V167.516H418.181V169.023H419.533V173.734C419.533 175.383 420.314 176.039 422.275 176.039C422.65 176.039 423.009 176.008 423.291 175.953V174.469C423.056 174.492 422.908 174.508 422.634 174.508C421.822 174.508 421.463 174.125 421.463 173.273V169.023H423.291V167.516H421.463V165.367H419.533Z" fill="black"/>
<rect x="334.5" y="143.5" width="107" height="53" rx="2.5" stroke="#BAC1CC"/>
</g>
<defs>
<filter id="filter0_dd_4385_55671" x="32" y="7" width="168" height="70" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4385_55671"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_4385_55671" result="effect2_dropShadow_4385_55671"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_4385_55671" result="shape"/>
</filter>
<filter id="filter1_dd_4385_55671" x="76" y="51" width="168" height="70" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4385_55671"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_4385_55671" result="effect2_dropShadow_4385_55671"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_4385_55671" result="shape"/>
</filter>
<filter id="filter2_dd_4385_55671" x="120" y="95" width="168" height="70" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4385_55671"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_4385_55671" result="effect2_dropShadow_4385_55671"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_4385_55671" result="shape"/>
</filter>
<filter id="filter3_dd_4385_55671" x="164" y="139" width="168" height="70" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4385_55671"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_4385_55671" result="effect2_dropShadow_4385_55671"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_4385_55671" result="shape"/>
</filter>
<filter id="filter4_dd_4385_55671" x="326" y="139" width="124" height="70" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4385_55671"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_4385_55671" result="effect2_dropShadow_4385_55671"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_4385_55671" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

+9
View File
@@ -0,0 +1,9 @@
<svg width="482" height="241" viewBox="0 0 482 241" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="0.5" y="0.5" width="481" height="240" fill="url(#pattern0)" stroke="#BAC1CC"/>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_4389_60550" transform="scale(0.00125 0.0025)"/>
</pattern>
<image id="image0_4389_60550" width="800" height="400" xlink:href="data:image/png;base64,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 truncated
</defs>
</svg>

After

Width:  |  Height:  |  Size: 90 KiB

@@ -0,0 +1,12 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default class ApplicationController extends Controller {
// =services
@service clockTick;
// =properties
now = new Date();
}
@@ -1,3 +1,3 @@
<h2 id="title">Welcome to Ember</h2>
{{t "errors.401.title"}}
<RelativeDatetimeLive @date={{this.now}} />
@@ -18,7 +18,7 @@ module('Integration | Component | error/message', function (hooks) {
);
assert.equal(
find('.rose-message-description').textContent.trim(),
'You are not authenticated. Please authenticate and try again later.'
'You are not signed in. Please sign in and try again later.'
);
await render(hbs`<Error::Message @status='403' />`);
assert.equal(
@@ -0,0 +1,14 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | Image', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
assert.expect(1);
await render(hbs`<Image @name="resource-creation" />`);
assert.ok(find('.image-container'));
});
});
@@ -0,0 +1,20 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find, click } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | loading-button', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<LoadingButton />`);
assert.ok(find('.loading-button'));
});
test('it executes a function on refresh button click', async function (assert) {
assert.expect(2);
this.onClick = () => assert.ok(true, 'refresh was clicked');
await render(hbs`<LoadingButton @onClick={{this.onClick}}/>`);
assert.ok(find('.loading-button'));
await click('button');
});
});
@@ -0,0 +1,38 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | relative-datetime-live', function (hooks) {
setupRenderingTest(hooks);
test('it renders a relative datetime', async function (assert) {
assert.expect(6);
const now = Date.now();
this.date = now - 10 * 1000;
await render(hbs`<RelativeDatetimeLive @date={{this.date}} />`);
assert.dom(this.element).hasText('10 seconds ago');
this.date = now - 10 * 60 * 1000;
await render(hbs`<RelativeDatetimeLive @date={{this.date}} />`);
assert.dom(this.element).hasText('10 minutes ago');
this.date = now - 10 * 60 * 60 * 1000;
await render(hbs`<RelativeDatetimeLive @date={{this.date}} />`);
assert.dom(this.element).hasText('10 hours ago');
this.date = now - 10 * 24 * 60 * 60 * 1000;
await render(hbs`<RelativeDatetimeLive @date={{this.date}} />`);
assert.dom(this.element).hasText('10 days ago');
this.date = now - 10 * 31 * 24 * 60 * 60 * 1000;
await render(hbs`<RelativeDatetimeLive @date={{this.date}} />`);
assert.dom(this.element).hasText('10 months ago');
this.date = now - 10 * 12 * 31 * 24 * 60 * 60 * 1000;
await render(hbs`<RelativeDatetimeLive @date={{this.date}} />`);
assert.dom(this.element).hasText('10 years ago');
});
});
@@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Service | clock-tick', function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let service = this.owner.lookup('service:clock-tick');
assert.ok(service);
});
});
+6 -3
View File
@@ -9,16 +9,18 @@ save: Save
submit: Submit
manage: Manage
confirm: Confirm
done: Done
ok: OK
deny: Deny
help: Need help?
next: Next
back: Back
retry: Retry
get-topic-help: Get help for this topic
copy-to-clipboard: Copy to Clipboard
copy-error-detail-to-clipboard: Copy error detail to clipboard
authenticate: Authenticate
deauthenticate: Deauthenticate
authenticate: Sign In
deauthenticate: Sign Out
choose-org: Choose Scope
choose-different-org: Choose a different scope
add-host-set: Create Host Set
@@ -36,4 +38,5 @@ toggle-secret: Toggle secret visibility
minimize: Minimize
fullscreen: Fullscreen
clear-all-filters: Clear all filters
learn-more: Learn more
learn-more: Learn more
refresh: Refresh
+39
View File
@@ -32,6 +32,8 @@ titles:
no-results: No Results
choose-a-provider: Choose a provider
provider: Provider
success: Success
create-resources: Create Resources
descriptions:
empty-set: There are no items to display yet. You may be able to add items or try back later.
origin-initialization: To get started, please enter your origin URL
@@ -50,3 +52,40 @@ themes:
system: System Default
light: Light
dark: Dark
onboarding:
quick-start:
titles:
choose-path: Welcome to Boundary
quick-setup: Quick setup
manual: Manual
create-resource: Creating your first target
resource-setup-info: We’ll set up scopes & a host catalog for you
host-address: Host Address
target-port: Target Port
toggle-resource-info: I have an IP address and port for my first host
descriptions:
choose-path: You’ve taken the first step towards making your infrastructure more secure. How do you want to get started?
quick-setup: I want to see how Boundary works, help me set up my first scopes and targets.
manual: I want to set up my first scopes and targets myself, starting with my first org.
create-resource: In Boundary, a “target” defines a server that your users will connect to.
resource-setup-info: Hosts are organized in host catalogs, which live in projects, which live in orgs. We will create these for you, and they can be edited or deleted later.
host-address: "Example: “192.168.0.1” or IPv6"
target-port: "Example: “22”"
success:
titles:
connect: Connect to your target
desktop: Using Boundary Desktop
developers: Developers
controller: Controller URL
creation-success: We have created your scopes and target
descriptions:
download: Download the Boundary Desktop app to browse and connect to targets (available for Windows, Mac, and Linux)
developers: You can also connect to targets using the Boundary CLI or API.
controller: Use this URL to sign in to Boundary
role: You can now connect to the target with the Boundary Desktop app, command-line (CLI) or API. Boundary grants access to resources based on roles, and we have added you to the `demo` role to give you access to this target. Make sure to add this role to any new users if you want them to access it too.
links:
install: Install the Boundary Desktop app
learn: Learn about Boundary Desktop app
cli: Learn about Boundary command-line (CLI)
api: Learn about Boundary API
+3 -1
View File
@@ -1,6 +1,6 @@
401:
title: You are not signed in
description: You are not authenticated. Please authenticate and try again later.
description: You are not signed in. Please sign in and try again later.
403:
title: You are not authorized
description: You must be granted permissions to view this data. Ask your administrator if you think you should have access.
@@ -19,3 +19,5 @@ authentication-failed:
title: Authentication Failed
origin-verification-failed:
description: Unable to connect to the specified origin. Please check the URL and try again.
quick-setup-failed:
description: We're sorry, quick setup was unable to generate all resources.
+6
View File
@@ -41,6 +41,9 @@ session_max_seconds:
session_connection_limit:
label: Maximum Connections
help: The maximum number of connections allowed per session. For unlimited, specify "-1".
worker_filter:
label: Worker Filter
help: Optional boolean expression to filter the workers that are allowed to satisfy this request.
host_set:
label: Host Set
grant_scope:
@@ -143,3 +146,6 @@ host:
label: Host
ip_addresses:
label: Latest IP Addresses
sync-interval:
label: Sync Interval
help: Number of seconds between the time Boundary syncs hosts in this set.
@@ -172,8 +172,8 @@ session:
title_plural: Credentials
secret:
label: Secret
credential_library:
title: Credential Library
credential_source:
title: Credential Source
actions:
raw-api:
show: View raw API output
@@ -278,6 +278,9 @@ target:
types:
tcp: TCP
ssh: SSH
help:
tcp: Connections are made over TCP to support a broad range of protocols, including SSH, RDP, databases, and more. This is the most general-purpose type.
ssh: Protocol-aware connections are made over SSH. Use when requiring SSH connections to remote hosts.
host-source:
title: Host Source
title_plural: Host Sources
@@ -315,6 +318,7 @@ credential-store:
delete: Delete Credential Store
types:
vault: Vault
static: Static
form:
address:
label: Address
+6 -3
View File
@@ -2,13 +2,16 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true,
// This is specific babel-config. If grows consider creating a babel config file
requireConfigFile: false,
babelOptions: {
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
},
// end of babel-config
},
plugins: ['ember'],
extends: [
+2 -1
View File
@@ -1,7 +1,8 @@
'use strict';
module.exports = {
extends: 'octane',
plugins: ['ember-template-lint-plugin-prettier'],
extends: ['octane', 'ember-template-lint-plugin-prettier:recommended'],
overrides: [
{
files: [
+6 -1
View File
@@ -40,16 +40,21 @@ List of available project commands. `yarn run <command-name>`
| build:development | Builds the dummy app in development mode. |
| build | Builds the dummy app for production. |
| lint | Runs all lint commands. |
| lint:fix | Runs automatic lint fixes for all files. |
| lint:hbs | Lints template `hbs` files. |
| lint:hbs:fix | Runs automatic lint fixes for `hbs` files. |
| lint:js | Lints `js` files. |
| lint:js:fix | Runs automatic lint fixes for `js` files. |
| lint:sass | Lints `scss` files. |
| format | Runs all auto-formatters. |
| format:js | Auto-formats `js` files using Prettier. |
| format:hbs | Auto-formats `hbs` files using Prettier. |
| format:sass | Auto-formats `scss` files using Prettier. |
| start | Runs the dummy app local server. |
| storybook | Runs the Storybook local server on port 6006. Be sure to start the standard server (see above) in a separate terminal. |
| test | Runs all tests. |
| test:all | Runs tests across multiple Ember versions with ember-try. |
| test:ember-compatibility | Runs tests across multiple Ember versions with ember-try. |
| precommit | Runs all lint, format and tests. |
| doc:toc | Automatically generates a table of contents for this README file. |
Additional commands in the monorepo package may affect this projects.
@@ -1,14 +1,12 @@
<span ...attributes
class="rose-badge {{if @style (concat "rose-badge-" @style)}}"
<span
...attributes
class='rose-badge {{if @style (concat 'rose-badge-' @style)}}'
>
{{#if @icon}}
<Rose::Icon
@name={{@icon}}
@size="medium"
/>
<Rose::Icon @name={{@icon}} @size='medium' />
{{/if}}
<span class="rose-badge-body">
<span class='rose-badge-body'>
{{yield}}
</span>
</span>
</span>
@@ -1,34 +1,29 @@
<button
...attributes
type={{if @submit "submit" "button"}}
disabled={{if @disabled "disabled"}}
class="{{@classNames}} {{if @style (concat "rose-button-" @style)}} {{if @iconLeft "has-icon-left"}} {{if @iconRight "has-icon-right"}} {{if @iconOnly "has-icon-only"}}"
>
type={{if @submit 'submit' 'button'}}
disabled={{if @disabled 'disabled'}}
class='{{@classNames}}
{{if @style (concat 'rose-button-' @style)}}
{{if @iconLeft 'has-icon-left'}}
{{if @iconRight 'has-icon-right'}}
{{if @iconOnly 'has-icon-only'}}'
>
<span class="rose-button-wrapper">
<span class='rose-button-wrapper'>
{{#if @iconLeft}}
<Rose::Icon
@name={{@iconLeft}}
@size="medium"
/>
<Rose::Icon @name={{@iconLeft}} @size='medium' />
{{/if}}
<span class="rose-button-body">
<span class='rose-button-body'>
{{yield}}
</span>
{{#if @iconOnly}}
<Rose::Icon
@name={{@iconOnly}}
@size="medium"
/>
<Rose::Icon @name={{@iconOnly}} @size='medium' />
{{/if}}
{{#if @iconRight}}
<Rose::Icon
@name={{@iconRight}}
@size="medium"
/>
<Rose::Icon @name={{@iconRight}} @size='medium' />
{{/if}}
</span>
</button>
</button>
@@ -0,0 +1,5 @@
import Component from '@glimmer/component';
export default class RoseButtonComponent extends Component {
// =attributes
}
@@ -1,34 +1,32 @@
<article ...attributes class="rose-card-link">
<article ...attributes class='rose-card-link'>
<LinkTo
title={{@title}}
@route={{if @route @route "index"}}
@route={{if @route @route 'index'}}
@model={{@model}}
>
<div class="rose-card-link-header">
<div class='rose-card-link-header'>
{{#if @title}}
<h2 class="rose-card-link-title">
<h2 class='rose-card-link-title'>
{{#if @icon}}
<Rose::Icon
@name={{@icon}}
@size="medium" />
<Rose::Icon @name={{@icon}} @size='medium' />
{{/if}}
<span class="rose-card-link-title-text">{{@title}}</span>
<span class='rose-card-link-title-text'>{{@title}}</span>
</h2>
{{/if}}
</div>
<div class="rose-card-link-body">
<div class='rose-card-link-body'>
{{#if @description}}
<p class="rose-card-link-description">{{@description}}</p>
<p class='rose-card-link-description'>{{@description}}</p>
{{/if}}
</div>
<div class="rose-card-link-footer">
<div class='rose-card-link-footer'>
{{#if @id}}
<p class="rose-card-link-footer-id">{{@id}}</p>
<p class='rose-card-link-footer-id'>{{@id}}</p>
{{/if}}
</div>
</LinkTo>
{{yield}}
</article>
</article>
@@ -1,8 +1,3 @@
<div
...attributes
class="rose-cards"
>
{{yield (hash
link=(component "rose/card/link")
)}}
</div>
<div ...attributes class='rose-cards'>
{{yield (hash link=(component 'rose/card/link'))}}
</div>
@@ -1,3 +1,3 @@
<div class="rose-dialog-body" tabindex="0">
<div class='rose-dialog-body' tabindex='0'>
{{yield}}
</div>
</div>
@@ -1,21 +1,21 @@
<div class="rose-dialog-cover-modal-overlay"></div>
<div class='rose-dialog-cover-modal-overlay'></div>
<section
...attributes
role="dialog"
class="rose-dialog-cover"
role='dialog'
class='rose-dialog-cover'
id={{this.id}}
aria-describedby={{concat "dialog-cover-header-" this.id}}
tabindex="0"
aria-describedby={{concat 'dialog-cover-header-' this.id}}
tabindex='0'
{{focus-trap}}
>
<header
class="rose-dialog-cover-header"
id={{concat "dialog-cover-header-" this.id}}
class='rose-dialog-cover-header'
id={{concat 'dialog-cover-header-' this.id}}
>
{{yield to="header"}}
{{yield to='header'}}
</header>
<div class="rose-dialog-cover-body">
{{yield to="body"}}
<div class='rose-dialog-cover-body'>
{{yield to='body'}}
</div>
</section>
</section>
@@ -1,41 +1,44 @@
{{#if @modal}}
<div class="rose-dialog-modal-overlay"></div>
<div class='rose-dialog-modal-overlay'></div>
<section
...attributes
role="dialog"
class="rose-dialog {{if @style (concat "rose-dialog-" @style)}} {{if @modal 'modal'}}"
role='dialog'
class='rose-dialog
{{if @style (concat 'rose-dialog-' @style)}}
{{if @modal 'modal'}}'
id={{this.id}}
aria-describedby={{concat "dialog-header-" this.id}}
aria-describedby={{concat 'dialog-header-' this.id}}
{{focus-trap}}
>
<header
class="rose-dialog-header"
id={{concat "dialog-header-" this.id}}
>
<header class='rose-dialog-header' id={{concat 'dialog-header-' this.id}}>
{{#if @icon}}
<Rose::Icon @name={{@icon}} @size="medium" />
<Rose::Icon @name={{@icon}} @size='medium' />
{{/if}}
<h2 class="rose-dialog-heading">{{@heading}}</h2>
<h2 class='rose-dialog-heading'>{{@heading}}</h2>
<button
type="button"
class="rose-dialog-dismiss"
type='button'
class='rose-dialog-dismiss'
title={{@dismissButtonText}}
{{on "click" (fn this.dismiss @dismiss)}}
{{on 'click' (fn this.dismiss @dismiss)}}
>
<Rose::Icon @name="flight-icons/svg/x-16" @size="small" />
<Rose::Icon @name='flight-icons/svg/x-16' @size='small' />
</button>
</header>
{{yield (hash
body=(component 'rose/dialog/body')
footer=(component 'rose/anonymous' tagName="footer" class="rose-dialog-footer")
)}}
{{yield
(hash
body=(component 'rose/dialog/body')
footer=(component
'rose/anonymous' tagName='footer' class='rose-dialog-footer'
)
)
}}
</section>
@@ -43,36 +46,42 @@
<section
...attributes
role="dialog"
class="rose-dialog {{if @style (concat "rose-dialog-" @style)}} {{if @modal 'modal'}}"
role='dialog'
class='rose-dialog
{{if @style (concat 'rose-dialog-' @style)}}
{{if @modal 'modal'}}'
>
{{#if @heading}}
<header class="rose-dialog-header">
<header class='rose-dialog-header'>
{{#if @icon}}
<Rose::Icon @name={{@icon}} @size="medium" />
<Rose::Icon @name={{@icon}} @size='medium' />
{{/if}}
<h2 class="rose-dialog-heading">{{@heading}}</h2>
<h2 class='rose-dialog-heading'>{{@heading}}</h2>
<button
type="button"
class="rose-dialog-dismiss"
type='button'
class='rose-dialog-dismiss'
title={{@dismissButtonText}}
{{on "click" (fn this.dismiss @dismiss)}}
{{on 'click' (fn this.dismiss @dismiss)}}
>
<Rose::Icon @name="flight-icons/svg/x-16" @size="small" />
<Rose::Icon @name='flight-icons/svg/x-16' @size='small' />
</button>
</header>
{{/if}}
{{yield (hash
body=(component 'rose/dialog/body')
footer=(component 'rose/anonymous' tagName="footer" class="rose-dialog-footer")
)}}
{{yield
(hash
body=(component 'rose/dialog/body')
footer=(component
'rose/anonymous' tagName='footer' class='rose-dialog-footer'
)
)
}}
</section>
{{/if}}
{{/if}}
@@ -1,19 +1,18 @@
<button
...attributes
type={{if @submit "submit" "button"}}
disabled={{if @disabled "disabled"}}
class="rose-dropdown-button {{if @style (concat "rose-dropdown-button-" @style)}} {{if @iconOnly "has-icon-only"}}"
>
<span class="rose-dropdown-button-wrapper">
<span class="rose-dropdown-button-body">
type={{if @submit 'submit' 'button'}}
disabled={{if @disabled 'disabled'}}
class='rose-dropdown-button
{{if @style (concat 'rose-dropdown-button-' @style)}}
{{if @iconOnly 'has-icon-only'}}'
>
<span class='rose-dropdown-button-wrapper'>
<span class='rose-dropdown-button-body'>
{{yield}}
</span>
{{#if @iconOnly}}
<Rose::Icon
@name={{@iconOnly}}
@size="medium"
/>
<Rose::Icon @name={{@iconOnly}} @size='medium' />
{{/if}}
</span>
</button>
</button>
@@ -1,22 +1,23 @@
<details
...attributes
class="rose-dropdown {{if @dropdownRight "rose-dropdown-right"}} {{if @style (concat "rose-dropdown-" @style)}}"
class='rose-dropdown
{{if @dropdownRight 'rose-dropdown-right'}}
{{if @style (concat 'rose-dropdown-' @style)}}'
{{on-click-outside this.close}}
>
<summary
class="rose-dropdown-trigger {{if @iconOnly "has-icon-only"}} {{if this.showCaret "show-caret"}}"
class='rose-dropdown-trigger
{{if @iconOnly 'has-icon-only'}}
{{if this.showCaret 'show-caret'}}'
title={{@text}}
>
{{#if @icon}}
<Rose::Icon
@name={{@icon}}
@size="medium"
/>
<Rose::Icon @name={{@icon}} @size='medium' />
{{/if}}
<span class="rose-dropdown-trigger-text">
<span class='rose-dropdown-trigger-text'>
{{@text}}
{{#if @count}}
<Rose::Badge>{{@count}}</Rose::Badge>
@@ -26,27 +27,35 @@
</summary>
{{#if @ignoreClickInside}}
<div class="rose-dropdown-content">
{{yield (hash
link=(component "rose/dropdown/link" style=this.style)
button=(component "rose/dropdown/button" style=this.style)
item=(component "rose/anonymous" class="rose-dropdown-item")
separator=(component "rose/anonymous" tagName="hr" class="rose-dropdown-separator")
section=(component "rose/dropdown/section" style=this.style)
key-value=(component "rose/dropdown/key-value")
)}}
<div class='rose-dropdown-content'>
{{yield
(hash
link=(component 'rose/dropdown/link' style=this.style)
button=(component 'rose/dropdown/button' style=this.style)
item=(component 'rose/anonymous' class='rose-dropdown-item')
separator=(component
'rose/anonymous' tagName='hr' class='rose-dropdown-separator'
)
section=(component 'rose/dropdown/section' style=this.style)
key-value=(component 'rose/dropdown/key-value')
)
}}
</div>
{{else}}
<div class="rose-dropdown-content" {{on-click-inside this.close}}>
{{yield (hash
link=(component "rose/dropdown/link" style=this.style)
button=(component "rose/dropdown/button" style=this.style)
item=(component "rose/anonymous" class="rose-dropdown-item")
separator=(component "rose/anonymous" tagName="hr" class="rose-dropdown-separator")
section=(component "rose/dropdown/section" style=this.style)
key-value=(component "rose/dropdown/key-value")
)}}
<div class='rose-dropdown-content' {{on-click-inside this.close}}>
{{yield
(hash
link=(component 'rose/dropdown/link' style=this.style)
button=(component 'rose/dropdown/button' style=this.style)
item=(component 'rose/anonymous' class='rose-dropdown-item')
separator=(component
'rose/anonymous' tagName='hr' class='rose-dropdown-separator'
)
section=(component 'rose/dropdown/section' style=this.style)
key-value=(component 'rose/dropdown/key-value')
)
}}
</div>
{{/if}}
</details>
</details>
Loaded 100 of 247 files, more files were not shown because too many files have changed in this diff. Show more