├── .editorconfig ├── .eslintrc.js ├── .github └── workflows │ └── nodejs.yml ├── .gitignore ├── .ignore ├── DEPLOY.md ├── LICENSE ├── README.md ├── android ├── .gitignore ├── app │ ├── .gitignore │ ├── build.gradle │ ├── capacitor.build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── getcapacitor │ │ │ └── myapp │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── matthiasprost │ │ │ │ └── scalewaymanager │ │ │ │ └── MainActivity.java │ │ └── res │ │ │ ├── drawable-land-hdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-ldpi │ │ │ └── splash.png │ │ │ ├── drawable-land-mdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-night-hdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-night-ldpi │ │ │ └── splash.png │ │ │ ├── drawable-land-night-mdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-night-xhdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-night-xxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-night-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-xhdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-xxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-night │ │ │ └── splash.png │ │ │ ├── drawable-port-hdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-ldpi │ │ │ └── splash.png │ │ │ ├── drawable-port-mdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-night-hdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-night-ldpi │ │ │ └── splash.png │ │ │ ├── drawable-port-night-mdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-night-xhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-night-xxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-night-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-xhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-xxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ ├── ic_launcher_background.xml │ │ │ └── splash.png │ │ │ ├── layout │ │ │ └── activity_main.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-ldpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ │ └── xml │ │ │ └── file_paths.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── getcapacitor │ │ └── myapp │ │ └── ExampleUnitTest.java ├── build.gradle ├── capacitor.settings.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── variables.gradle ├── angular.json ├── capacitor.config.json ├── config.xml ├── e2e ├── protractor.conf.js ├── src │ ├── app.e2e-spec.ts │ └── app.po.ts └── tsconfig.e2e.json ├── ionic.config.json ├── ios ├── .gitignore └── App │ ├── App.xcodeproj │ └── project.pbxproj │ ├── App.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── App │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon-512@2x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── Splash.imageset │ │ │ ├── Contents.json │ │ │ ├── Default@1x~universal~anyany-dark.png │ │ │ ├── Default@1x~universal~anyany.png │ │ │ ├── Default@2x~universal~anyany-dark.png │ │ │ ├── Default@2x~universal~anyany.png │ │ │ ├── Default@3x~universal~anyany-dark.png │ │ │ ├── Default@3x~universal~anyany.png │ │ │ ├── splash-2732x2732-1.png │ │ │ ├── splash-2732x2732-2.png │ │ │ └── splash-2732x2732.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── capacitor.config.json │ └── config.xml │ ├── Podfile │ └── Podfile.lock ├── package.json ├── proxy.conf.js ├── resources ├── README.md ├── android │ ├── adaptiveicon │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ └── values │ │ │ └── ic_launcher_background.xml │ ├── icon │ │ ├── drawable-hdpi-icon.png │ │ ├── drawable-ldpi-icon.png │ │ ├── drawable-mdpi-icon.png │ │ ├── drawable-xhdpi-icon.png │ │ ├── drawable-xxhdpi-icon.png │ │ └── drawable-xxxhdpi-icon.png │ ├── splash │ │ ├── drawable-land-hdpi-screen.png │ │ ├── drawable-land-ldpi-screen.png │ │ ├── drawable-land-mdpi-screen.png │ │ ├── drawable-land-xhdpi-screen.png │ │ ├── drawable-land-xxhdpi-screen.png │ │ ├── drawable-land-xxxhdpi-screen.png │ │ ├── drawable-port-hdpi-screen.png │ │ ├── drawable-port-ldpi-screen.png │ │ ├── drawable-port-mdpi-screen.png │ │ ├── drawable-port-xhdpi-screen.png │ │ ├── drawable-port-xxhdpi-screen.png │ │ └── drawable-port-xxxhdpi-screen.png │ └── xml │ │ └── network_security_config.xml ├── icon.png ├── ios │ ├── icon │ │ ├── icon-1024.png │ │ ├── icon-108@2x.png │ │ ├── icon-20.png │ │ ├── icon-20@2x.png │ │ ├── icon-20@3x.png │ │ ├── icon-24@2x.png │ │ ├── icon-27.5@2x.png │ │ ├── icon-29.png │ │ ├── icon-29@2x.png │ │ ├── icon-29@3x.png │ │ ├── icon-40.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-44@2x.png │ │ ├── icon-50.png │ │ ├── icon-50@2x.png │ │ ├── icon-60.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-72.png │ │ ├── icon-72@2x.png │ │ ├── icon-76.png │ │ ├── icon-76@2x.png │ │ ├── icon-83.5@2x.png │ │ ├── icon-86@2x.png │ │ ├── icon-98@2x.png │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ ├── icon-small@3x.png │ │ ├── icon.png │ │ └── icon@2x.png │ └── splash │ │ ├── Default-1792h~iphone.png │ │ ├── Default-2436h.png │ │ ├── Default-2688h~iphone.png │ │ ├── Default-568h@2x~iphone.png │ │ ├── Default-667h.png │ │ ├── Default-736h.png │ │ ├── Default-Landscape-1792h~iphone.png │ │ ├── Default-Landscape-2436h.png │ │ ├── Default-Landscape-2688h~iphone.png │ │ ├── Default-Landscape-736h.png │ │ ├── Default-Landscape@2x~ipad.png │ │ ├── Default-Landscape@~ipadpro.png │ │ ├── Default-Landscape~ipad.png │ │ ├── Default-Portrait@2x~ipad.png │ │ ├── Default-Portrait@~ipadpro.png │ │ ├── Default-Portrait~ipad.png │ │ ├── Default@2x~iphone.png │ │ ├── Default@2x~universal~anyany.png │ │ └── Default~iphone.png └── splash.png ├── scripts └── resources.js ├── src ├── app │ ├── app-routing.module.ts │ ├── app.component.html │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── app.scss │ ├── components │ │ ├── components.module.ts │ │ ├── error │ │ │ ├── error.component.html │ │ │ ├── error.component.scss │ │ │ ├── error.component.spec.ts │ │ │ └── error.component.ts │ │ ├── graph │ │ │ ├── graph.component.html │ │ │ ├── graph.component.scss │ │ │ ├── graph.component.spec.ts │ │ │ └── graph.component.ts │ │ ├── list │ │ │ ├── list.component.html │ │ │ ├── list.component.scss │ │ │ ├── list.component.spec.ts │ │ │ └── list.component.ts │ │ └── loader │ │ │ ├── loader.component.html │ │ │ ├── loader.component.scss │ │ │ ├── loader.component.spec.ts │ │ │ └── loader.component.ts │ ├── guards │ │ ├── double-auth │ │ │ ├── double-auth.guard.spec.ts │ │ │ └── double-auth.guard.ts │ │ ├── home │ │ │ ├── home.guard.spec.ts │ │ │ └── home.guard.ts │ │ └── login │ │ │ ├── login.guard.spec.ts │ │ │ └── login.guard.ts │ ├── helpers │ │ └── mergeZones.ts │ ├── pages │ │ ├── about │ │ │ ├── about.module.ts │ │ │ ├── about.page.html │ │ │ ├── about.page.scss │ │ │ ├── about.page.spec.ts │ │ │ └── about.page.ts │ │ ├── account │ │ │ ├── account.module.ts │ │ │ ├── account.page.html │ │ │ ├── account.page.scss │ │ │ ├── account.page.spec.ts │ │ │ ├── account.page.ts │ │ │ ├── change-organization │ │ │ │ ├── change-organization.module.ts │ │ │ │ ├── change-organization.page.html │ │ │ │ ├── change-organization.page.scss │ │ │ │ ├── change-organization.page.spec.ts │ │ │ │ └── change-organization.page.ts │ │ │ ├── change-project │ │ │ │ ├── change-project.module.ts │ │ │ │ ├── change-project.page.html │ │ │ │ ├── change-project.page.scss │ │ │ │ ├── change-project.page.spec.ts │ │ │ │ └── change-project.page.ts │ │ │ ├── ssh-keys │ │ │ │ ├── add-ssh-key │ │ │ │ │ ├── add-ssh-key.module.ts │ │ │ │ │ ├── add-ssh-key.page.html │ │ │ │ │ ├── add-ssh-key.page.scss │ │ │ │ │ ├── add-ssh-key.page.spec.ts │ │ │ │ │ └── add-ssh-key.page.ts │ │ │ │ ├── ssh-keys.module.ts │ │ │ │ ├── ssh-keys.page.html │ │ │ │ ├── ssh-keys.page.scss │ │ │ │ ├── ssh-keys.page.spec.ts │ │ │ │ └── ssh-keys.page.ts │ │ │ └── tokens │ │ │ │ ├── tokens.module.ts │ │ │ │ ├── tokens.page.html │ │ │ │ ├── tokens.page.scss │ │ │ │ ├── tokens.page.spec.ts │ │ │ │ └── tokens.page.ts │ │ ├── auth │ │ │ ├── double-auth │ │ │ │ ├── double-auth.module.ts │ │ │ │ ├── double-auth.page.html │ │ │ │ ├── double-auth.page.scss │ │ │ │ ├── double-auth.page.spec.ts │ │ │ │ └── double-auth.page.ts │ │ │ └── login │ │ │ │ ├── help │ │ │ │ ├── help.module.ts │ │ │ │ ├── help.page.html │ │ │ │ ├── help.page.scss │ │ │ │ ├── help.page.spec.ts │ │ │ │ └── help.page.ts │ │ │ │ ├── login.module.ts │ │ │ │ ├── login.page.html │ │ │ │ ├── login.page.scss │ │ │ │ ├── login.page.spec.ts │ │ │ │ └── login.page.ts │ │ ├── billing │ │ │ ├── billing.module.ts │ │ │ ├── billing.page.html │ │ │ ├── billing.page.scss │ │ │ ├── billing.page.spec.ts │ │ │ └── billing.page.ts │ │ ├── home │ │ │ ├── home.module.ts │ │ │ ├── home.page.html │ │ │ ├── home.page.scss │ │ │ ├── home.page.spec.ts │ │ │ └── home.page.ts │ │ ├── products │ │ │ ├── bmaas │ │ │ │ ├── bmaas.module.ts │ │ │ │ ├── bmaas.page.html │ │ │ │ ├── bmaas.page.scss │ │ │ │ ├── bmaas.page.spec.ts │ │ │ │ ├── bmaas.page.ts │ │ │ │ └── details │ │ │ │ │ ├── details.module.ts │ │ │ │ │ ├── details.page.html │ │ │ │ │ ├── details.page.scss │ │ │ │ │ ├── details.page.spec.ts │ │ │ │ │ └── details.page.ts │ │ │ ├── buckets │ │ │ │ ├── add-bucket │ │ │ │ │ ├── add-bucket.module.ts │ │ │ │ │ ├── add-bucket.page.html │ │ │ │ │ ├── add-bucket.page.scss │ │ │ │ │ ├── add-bucket.page.spec.ts │ │ │ │ │ └── add-bucket.page.ts │ │ │ │ ├── buckets.module.ts │ │ │ │ ├── buckets.page.html │ │ │ │ ├── buckets.page.scss │ │ │ │ ├── buckets.page.spec.ts │ │ │ │ ├── buckets.page.ts │ │ │ │ └── objects │ │ │ │ │ ├── objects.module.ts │ │ │ │ │ ├── objects.page.html │ │ │ │ │ ├── objects.page.scss │ │ │ │ │ ├── objects.page.spec.ts │ │ │ │ │ ├── objects.page.ts │ │ │ │ │ └── options │ │ │ │ │ ├── obj-infos │ │ │ │ │ ├── obj-infos.module.ts │ │ │ │ │ ├── obj-infos.page.html │ │ │ │ │ ├── obj-infos.page.scss │ │ │ │ │ ├── obj-infos.page.spec.ts │ │ │ │ │ └── obj-infos.page.ts │ │ │ │ │ ├── options.module.ts │ │ │ │ │ ├── options.page.html │ │ │ │ │ ├── options.page.scss │ │ │ │ │ ├── options.page.spec.ts │ │ │ │ │ └── options.page.ts │ │ │ └── instances │ │ │ │ ├── details │ │ │ │ ├── details.module.ts │ │ │ │ ├── details.page.html │ │ │ │ ├── details.page.scss │ │ │ │ ├── details.page.spec.ts │ │ │ │ └── details.page.ts │ │ │ │ ├── instances.module.ts │ │ │ │ ├── instances.page.html │ │ │ │ ├── instances.page.scss │ │ │ │ ├── instances.page.spec.ts │ │ │ │ └── instances.page.ts │ │ └── settings │ │ │ ├── settings.module.ts │ │ │ ├── settings.page.html │ │ │ ├── settings.page.scss │ │ │ ├── settings.page.spec.ts │ │ │ └── settings.page.ts │ ├── pipes │ │ ├── billing-state-icon │ │ │ ├── billing-state-icon.pipe.spec.ts │ │ │ └── billing-state-icon.pipe.ts │ │ ├── file-size │ │ │ ├── file-size.pipe.spec.ts │ │ │ └── file-size.pipe.ts │ │ ├── pipes.module.ts │ │ ├── server-icon │ │ │ ├── server-icon.pipe.spec.ts │ │ │ └── server-icon.pipe.ts │ │ ├── total-volume-space │ │ │ ├── total-volumes-space.pipe.spec.ts │ │ │ └── total-volumes-space.pipe.ts │ │ └── zone-flag │ │ │ ├── zone-flag.pipe.spec.ts │ │ │ └── zone-flag.pipe.ts │ └── services │ │ ├── api │ │ ├── api.service.spec.ts │ │ ├── api.service.ts │ │ └── object-api.service.ts │ │ ├── billing │ │ ├── billing.dto.ts │ │ ├── billing.service.spec.ts │ │ └── billing.service.ts │ │ ├── bmaas │ │ ├── bmaas.dto.ts │ │ ├── bmaas.service.spec.ts │ │ ├── bmaas.service.ts │ │ └── config.ts │ │ ├── nav │ │ ├── nav-params.service.spec.ts │ │ └── nav-params.service.ts │ │ ├── object │ │ ├── config.ts │ │ ├── object.dto.ts │ │ ├── object.service.spec.ts │ │ └── object.service.ts │ │ ├── servers │ │ ├── actions.dto.ts │ │ ├── config.ts │ │ ├── server.dto.ts │ │ ├── servers.service.spec.ts │ │ └── servers.service.ts │ │ └── user │ │ ├── account │ │ ├── account.dto.ts │ │ ├── account.service.spec.ts │ │ └── account.service.ts │ │ ├── auth │ │ ├── auth.service.spec.ts │ │ └── auth.service.ts │ │ └── project │ │ ├── project.dto.ts │ │ ├── project.service.spec.ts │ │ ├── project.service.ts │ │ ├── ssh-key │ │ ├── ssh-keys.dto.ts │ │ ├── ssh-keys.service.spec.ts │ │ └── ssh-keys.service.ts │ │ └── tokens │ │ ├── tokens.dto.ts │ │ ├── tokens.service.spec.ts │ │ └── tokens.service.ts ├── assets │ ├── icon-background.png │ ├── icon-foreground.png │ ├── icon-only.png │ ├── icon │ │ └── favicon.png │ ├── icons │ │ ├── icon-128.webp │ │ ├── icon-192.webp │ │ ├── icon-256.webp │ │ ├── icon-48.webp │ │ ├── icon-512.webp │ │ ├── icon-72.webp │ │ └── icon-96.webp │ ├── img │ │ ├── alpine.svg │ │ ├── arch.svg │ │ ├── background.svg │ │ ├── centos.svg │ │ ├── debian.svg │ │ ├── fedora.svg │ │ ├── france.svg │ │ ├── github-logo.svg │ │ ├── gitlab.svg │ │ ├── invoice.svg │ │ ├── key.svg │ │ ├── logo-purple.svg │ │ ├── logo-white.svg │ │ ├── netherlands.svg │ │ ├── openvpn.svg │ │ ├── profile.svg │ │ ├── server.svg │ │ ├── ubuntu.svg │ │ └── warsaw.svg │ ├── splash-dark.png │ └── splash.png ├── global.scss ├── index.html ├── karma.conf.js ├── main.ts ├── manifest.webmanifest ├── polyfills.ts ├── test.ts ├── theme │ └── variables.scss ├── tsconfig.app.json ├── tsconfig.spec.json └── zone-flags.ts ├── tsconfig.app.json ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | 10 | # We recommend you to keep these unchanged 11 | end_of_line = lf 12 | charset = utf-8 13 | trim_trailing_whitespace = true 14 | insert_final_newline = true 15 | 16 | [*.md] 17 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@ionic/eslint-config/recommended'], 3 | overrides: [{ 4 | files: '*.ts', 5 | rules: { 6 | '@typescript-eslint/consistent-type-imports': 'off', 7 | 8 | // Typescript 3.1 doesn't support optional chaining upgrade is needed 9 | '@typescript-eslint/prefer-optional-chain': 'off' 10 | } 11 | }] 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Scaleway Manager CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - release 8 | - CI 9 | 10 | jobs: 11 | Linux_Build: 12 | 13 | runs-on: self-hosted 14 | 15 | steps: 16 | - uses: actions/checkout@v1 17 | 18 | - run: npm ci 19 | 20 | - name: Setup Ionic & Cordova 21 | uses: coturiv/setup-ionic@v1 22 | with: 23 | cordova-version: 9.0.0 24 | 25 | - name: Ionic Build 26 | run: | 27 | ionic info 28 | ionic build 29 | 30 | 31 | Android_Build: 32 | 33 | runs-on: self-hosted 34 | 35 | steps: 36 | - uses: actions/checkout@v1 37 | 38 | - run: npm ci 39 | 40 | - name: Setup Ionic & Cordova 41 | uses: coturiv/setup-ionic@v1.0.0 42 | with: 43 | # Version range or exact version of Cordova to use 44 | cordova-version: 9.0.0 45 | # Version range or exact version of Ionic to use 46 | ionic-version: 5.4.11 47 | # Whether to install Java 48 | install-java: true 49 | # Whether to install CocoaPods 50 | install-pods: false 51 | 52 | - name: Android Build 53 | run: | 54 | ionic info 55 | ionic cordova build android --prod 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.angular/cache 2 | # Specifies intentionally untracked files to ignore when using Git 3 | # http://git-scm.com/docs/gitignore 4 | 5 | *~ 6 | *.sw[mnpcod] 7 | *.log 8 | *.tmp 9 | *.tmp.* 10 | log.txt 11 | *.sublime-project 12 | *.sublime-workspace 13 | .vscode/ 14 | npm-debug.log* 15 | 16 | .idea/ 17 | .ionic/ 18 | .sourcemaps/ 19 | .sass-cache/ 20 | .tmp/ 21 | .versions/ 22 | .zed 23 | coverage/ 24 | www/ 25 | node_modules/ 26 | tmp/ 27 | temp/ 28 | platforms/ 29 | plugins/ 30 | plugins/android.json 31 | plugins/ios.json 32 | $RECYCLE.BIN/ 33 | 34 | .DS_Store 35 | Thumbs.db 36 | UserInterfaceState.xcuserstate 37 | 38 | src/environments/ 39 | -------------------------------------------------------------------------------- /.ignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .editconfig 3 | .git 4 | .github 5 | .gitignore 6 | .idea 7 | android 8 | ios 9 | angular.json 10 | capacitor.config.json 11 | config.xml 12 | e2e 13 | ionic.config.json 14 | ios 15 | package-lock,json 16 | package.json 17 | plugins 18 | www 19 | tslint.json 20 | tsconfig.json 21 | webpack.config.js 22 | src/tsconfig.app.json 23 | tsconfig.spec.json 24 | tslint.json 25 | zone-flag.ts 26 | -------------------------------------------------------------------------------- /DEPLOY.md: -------------------------------------------------------------------------------- 1 | This file is a personal reminder for deploy, don't mind about it :) 2 | 3 | ## Prerequisite 4 | 5 | Whatever platform you're trying to test or to deploy you need your packages to be installed: 6 | 7 | ```sh 8 | rm -rf node_modules && npm i 9 | ``` 10 | 11 | ## iOS 12 | 13 | #### Requirements 14 | 15 | - Macbook (Can be a VM with VMWare but expect it to be slow as hell) 16 | - Xcode 17 | - Ionic 18 | - Capacitor 19 | 20 | #### Build 21 | 22 | 1. Run `yarn run build:ios` 23 | 2. It should open xcode, you can start it on any emulator or device 24 | 25 | #### Deploy 26 | 27 | 1. Run `yarn run build:ios` 28 | 2. Change the version of the app + build number in xcode 29 | 3. Click on `Product > Archive` then `Distribute App` and follow the steps 30 | 4. That's it, it should be on App Store Connect 31 | 32 | ## Android 33 | 34 | #### Requirements 35 | 36 | - Android Studio 37 | - Android SDK 38 | - Ionic 39 | - Capacitor 40 | 41 | #### Test 42 | 43 | 1. Run `yarn run build:android` 44 | 2. It should open Android Studio, you can start it on any emulator or device 45 | 46 | #### Deploy 47 | 48 | 1. Run `yarn run build:android` 49 | 2. Change version into `android > app > build.gradle`: 50 | ``` 51 | versionCode 20005 52 | versionName "2.0.5" 53 | ``` 54 | 3. Then `Build > Generate Signed Bundle / APK > Android App Bundle` choose Key Store (*/mypath/mykey.jks*) and put `scaleway` as alias 55 | 4. Upload manually `.aab` file on Google Play Store 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | logo 3 |

4 | 5 | # Scaleway Manager 6 | 7 | Scaleway Manager is an open source mobile application. The application is using [Scaleway API](https://developers.scaleway.com/en/) to allow you to access to your cloud resources. 8 | 9 | The main idea is to be able to monitor and do actions on cloud resources directly trough your phone. 10 | 11 | We do not sell / use your data at any moment, we only make call to Scaleway API. If you're still worried about your security please enable double authentication on Scaleway. 12 | 13 | 14 | ### Download 15 | 16 | The application is available on Apple Store and Play Store **for free**! 17 | 18 | **Apple Store**: https://itunes.apple.com/us/app/scaleway-manager/id1415090286?mt=8 19 | 20 | **Google Play Store**: https://play.google.com/store/apps/details?id=com.matthiasprost.scalewaymanager 21 | 22 | --- 23 | 24 | ### Development 25 | 26 | ##### Requirements 27 | 28 | - Node.js 29 | - npm 30 | - IONIC - `npm install -g ionic` 31 | - Capacitor - `npm install -g capacitor` 32 | 33 | ##### Installation 34 | 35 | 1. Clone the repo 36 | 2. Run `npm install` 37 | 38 | ##### Live build / Test 39 | 40 | 1. Run `ionic serve` 41 | 2. Go on [http://localhost:8100/](http://localhost:8100/) 42 | 43 | --- 44 | 45 | ### Contributors 46 | 47 | ##### Quentin Lejard - valde 48 | 49 | GitLab: [https://framagit.org/valde](https://framagit.org/valde) 50 | 51 | Twitter: [https://twitter.com/__valde__](https://twitter.com/__valde__) 52 | -------------------------------------------------------------------------------- /android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep 3 | -------------------------------------------------------------------------------- /android/app/capacitor.build.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | 3 | android { 4 | compileOptions { 5 | sourceCompatibility JavaVersion.VERSION_17 6 | targetCompatibility JavaVersion.VERSION_17 7 | } 8 | } 9 | 10 | apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 | dependencies { 12 | implementation project(':capacitor-status-bar') 13 | 14 | } 15 | 16 | 17 | if (hasProperty('postBuildExtras')) { 18 | postBuildExtras() 19 | } 20 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import android.content.Context; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | import androidx.test.platform.app.InstrumentationRegistry; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * @see Testing documentation 15 | */ 16 | @RunWith(AndroidJUnit4.class) 17 | public class ExampleInstrumentedTest { 18 | 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 23 | 24 | assertEquals("com.getcapacitor.app", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/matthiasprost/scalewaymanager/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.matthiasprost.scalewaymanager; 2 | 3 | import com.getcapacitor.BridgeActivity; 4 | 5 | public class MainActivity extends BridgeActivity {} 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-ldpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-ldpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-night-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-night-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-night-ldpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-night-ldpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-night-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-night-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-night-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-night-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-night-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-night-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-night/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-ldpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-ldpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-night-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-night-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-night-ldpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-night-ldpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-night-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-night-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-night-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-night-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-night-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-night-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Scaleway Manager 4 | Scaleway Manager 5 | com.matthiasprost.scalewaymanager 6 | com.matthiasprost.scalewaymanager 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | 14 | @Test 15 | public void addition_isCorrect() throws Exception { 16 | assertEquals(4, 2 + 2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:8.5.1' 11 | classpath 'com.google.gms:google-services:4.4.0' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | apply from: "variables.gradle" 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | mavenCentral() 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /android/capacitor.settings.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | include ':capacitor-android' 3 | project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') 4 | 5 | include ':capacitor-status-bar' 6 | project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android') 7 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # AndroidX package structure to make it clearer which packages are bundled with the 20 | # Android operating system, and which are packaged with your app's APK 21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 22 | android.useAndroidX=true 23 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /android/variables.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minSdkVersion = 22 3 | compileSdkVersion = 34 4 | targetSdkVersion = 34 5 | androidxActivityVersion = '1.8.0' 6 | androidxAppCompatVersion = '1.6.1' 7 | androidxCoordinatorLayoutVersion = '1.2.0' 8 | androidxCoreVersion = '1.12.0' 9 | androidxFragmentVersion = '1.6.2' 10 | coreSplashScreenVersion = '1.0.1' 11 | androidxWebkitVersion = '1.9.0' 12 | junitVersion = '4.13.2' 13 | androidxJunitVersion = '1.1.5' 14 | androidxEspressoCoreVersion = '3.5.1' 15 | cordovaAndroidVersion = '10.1.1' 16 | } -------------------------------------------------------------------------------- /capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "com.matthiasprost.scalewaymanager", 3 | "appName": "Scaleway Manager", 4 | "webDir": "www", 5 | "plugins": { 6 | "CapacitorHttp": { 7 | "enabled": true 8 | } 9 | }, 10 | "cordova": { 11 | "preferences": { 12 | "ScrollEnabled": "false", 13 | "android-minSdkVersion": "19", 14 | "BackupWebStorage": "none", 15 | "SplashMaintainAspectRatio": "true", 16 | "FadeSplashScreenDuration": "300", 17 | "SplashShowOnlyFirstTime": "false", 18 | "SplashScreen": "screen", 19 | "SplashScreenDelay": "3000", 20 | "StatusBarOverlaysWebView": "true", 21 | "ShowSplashScreenSpinner": "false", 22 | "WKWebViewOnly": "true" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('new App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | describe('default screen', () => { 10 | beforeEach(() => { 11 | page.navigateTo('/home'); 12 | }); 13 | it('should have a title saying Home', () => { 14 | page.getPageOneTitleText().then(title => { 15 | expect(title).toEqual('Home'); 16 | }); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(destination) { 5 | return browser.get(destination); 6 | } 7 | 8 | getTitle() { 9 | return browser.getTitle(); 10 | } 11 | 12 | getPageOneTitleText() { 13 | return element(by.tagName('app-home')).element(by.deepCss('ion-title')).getText(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Scaleway-Manager", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "angular", 7 | "id": "82450576" 8 | } 9 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | App/build 2 | App/Pods 3 | App/output 4 | App/App/public 5 | DerivedData 6 | xcuserdata 7 | 8 | # Cordova plugins for Capacitor 9 | capacitor-cordova-ios-plugins 10 | 11 | # Generated Config files 12 | App/App/capacitor.config.json 13 | App/App/config.xml 14 | -------------------------------------------------------------------------------- /ios/App/App.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "size": "1024x1024", 6 | "filename": "AppIcon-512@2x.png", 7 | "platform": "ios" 8 | } 9 | ], 10 | "info": { 11 | "author": "xcode", 12 | "version": 1 13 | } 14 | } -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "Default@1x~universal~anyany.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "filename": "Default@2x~universal~anyany.png", 11 | "scale": "2x" 12 | }, 13 | { 14 | "idiom": "universal", 15 | "filename": "Default@3x~universal~anyany.png", 16 | "scale": "3x" 17 | }, 18 | { 19 | "appearances": [ 20 | { 21 | "appearance": "luminosity", 22 | "value": "dark" 23 | } 24 | ], 25 | "idiom": "universal", 26 | "scale": "1x", 27 | "filename": "Default@1x~universal~anyany-dark.png" 28 | }, 29 | { 30 | "appearances": [ 31 | { 32 | "appearance": "luminosity", 33 | "value": "dark" 34 | } 35 | ], 36 | "idiom": "universal", 37 | "scale": "2x", 38 | "filename": "Default@2x~universal~anyany-dark.png" 39 | }, 40 | { 41 | "appearances": [ 42 | { 43 | "appearance": "luminosity", 44 | "value": "dark" 45 | } 46 | ], 47 | "idiom": "universal", 48 | "scale": "3x", 49 | "filename": "Default@3x~universal~anyany-dark.png" 50 | } 51 | ], 52 | "info": { 53 | "version": 1, 54 | "author": "xcode" 55 | } 56 | } -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Default@1x~universal~anyany-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/Default@1x~universal~anyany-dark.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Default@1x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/Default@1x~universal~anyany.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Default@2x~universal~anyany-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/Default@2x~universal~anyany-dark.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Default@2x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/Default@2x~universal~anyany.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Default@3x~universal~anyany-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/Default@3x~universal~anyany-dark.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Default@3x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/Default@3x~universal~anyany.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /ios/App/App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ios/App/App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Scaleway Manager 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ios/App/App/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "com.matthiasprost.scalewaymanager", 3 | "appName": "Scaleway Manager", 4 | "webDir": "www", 5 | "plugins": { 6 | "CapacitorHttp": { 7 | "enabled": true 8 | } 9 | }, 10 | "cordova": { 11 | "preferences": { 12 | "ScrollEnabled": "false", 13 | "android-minSdkVersion": "19", 14 | "BackupWebStorage": "none", 15 | "SplashMaintainAspectRatio": "true", 16 | "FadeSplashScreenDuration": "300", 17 | "SplashShowOnlyFirstTime": "false", 18 | "SplashScreen": "screen", 19 | "SplashScreenDelay": "3000", 20 | "StatusBarOverlaysWebView": "true", 21 | "ShowSplashScreenSpinner": "false", 22 | "WKWebViewOnly": "true" 23 | } 24 | }, 25 | "packageClassList": [ 26 | "StatusBarPlugin" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /ios/App/App/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ios/App/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers' 2 | 3 | platform :ios, '13.0' 4 | use_frameworks! 5 | 6 | # workaround to avoid Xcode caching of Pods that requires 7 | # Product -> Clean Build Folder after new Cordova plugins installed 8 | # Requires CocoaPods 1.6 or newer 9 | install! 'cocoapods', :disable_input_output_paths => true 10 | 11 | def capacitor_pods 12 | pod 'Capacitor', :path => '../../node_modules/@capacitor/ios' 13 | pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' 14 | pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar' 15 | end 16 | 17 | target 'App' do 18 | capacitor_pods 19 | # Add your Pods here 20 | end 21 | 22 | post_install do |installer| 23 | assertDeploymentTarget(installer) 24 | end 25 | -------------------------------------------------------------------------------- /ios/App/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Capacitor (6.1.2): 3 | - CapacitorCordova 4 | - CapacitorCordova (6.1.2) 5 | - CapacitorStatusBar (6.0.1): 6 | - Capacitor 7 | 8 | DEPENDENCIES: 9 | - "Capacitor (from `../../node_modules/@capacitor/ios`)" 10 | - "CapacitorCordova (from `../../node_modules/@capacitor/ios`)" 11 | - "CapacitorStatusBar (from `../../node_modules/@capacitor/status-bar`)" 12 | 13 | EXTERNAL SOURCES: 14 | Capacitor: 15 | :path: "../../node_modules/@capacitor/ios" 16 | CapacitorCordova: 17 | :path: "../../node_modules/@capacitor/ios" 18 | CapacitorStatusBar: 19 | :path: "../../node_modules/@capacitor/status-bar" 20 | 21 | SPEC CHECKSUMS: 22 | Capacitor: 679f9673fdf30597493a6362a5d5bf233d46abc2 23 | CapacitorCordova: f48c89f96c319101cd2f0ce8a2b7449b5fb8b3dd 24 | CapacitorStatusBar: b81d4fb5d4e0064c712018071b3ab4b810b39a63 25 | 26 | PODFILE CHECKSUM: 816cca1e0996e5a4f8a6d3f70aad051f862b11c2 27 | 28 | COCOAPODS: 1.11.3 29 | -------------------------------------------------------------------------------- /proxy.conf.js: -------------------------------------------------------------------------------- 1 | const PROXY_CONFIG = { 2 | "/api/*": { 3 | "target": "https://api.scaleway.com", 4 | "changeOrigin": true, 5 | "secure": false, 6 | "pathRewrite": { 7 | "^/api": "" 8 | }, 9 | "logLevel": "debug" 10 | }, 11 | "/s3/*": { 12 | target: true, 13 | router: function (req) { 14 | var subhost = req.headers.subhost; 15 | var path = req.headers.path; 16 | var zone = req.headers.zone; 17 | var target = `https://${subhost ? subhost + '.' : ''}s3.${zone}.scw.cloud${path ? path : ''}`; 18 | console.log(target); 19 | return target; 20 | }, 21 | changeOrigin: true, 22 | secure: false, 23 | "pathRewrite": { 24 | "^/s3": "" 25 | }, 26 | "logLevel": "debug" 27 | }, 28 | }; 29 | 30 | module.exports = PROXY_CONFIG; 31 | -------------------------------------------------------------------------------- /resources/README.md: -------------------------------------------------------------------------------- 1 | These are Cordova resources. You can replace icon.png and splash.png and run 2 | `ionic cordova resources` to generate custom icons and splash screens for your 3 | app. See `ionic cordova resources --help` for details. 4 | 5 | Cordova reference documentation: 6 | 7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html 8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/ 9 | -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/adaptiveicon/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /resources/android/adaptiveicon/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #510098 4 | -------------------------------------------------------------------------------- /resources/android/icon/drawable-hdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/icon/drawable-hdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-ldpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/icon/drawable-ldpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-mdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/icon/drawable-mdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/icon/drawable-xhdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/icon/drawable-xxhdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xxxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/icon/drawable-xxxhdpi-icon.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-land-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-land-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-land-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-land-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-land-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-land-xxxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-port-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-port-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-port-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-port-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-port-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/android/splash/drawable-port-xxxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | localhost 5 | 6 | 7 | -------------------------------------------------------------------------------- /resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/icon.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-1024.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-108@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-108@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-20.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-20@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-20@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-24@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-24@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-27.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-27.5@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-29.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-29@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-29@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-40.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-40@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-40@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-44@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-44@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-50.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-50@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-60.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-60@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-60@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-72.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-72@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-76.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-76@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-83.5@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-86@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-86@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-98@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-98@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-small.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-small@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon-small@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon.png -------------------------------------------------------------------------------- /resources/ios/icon/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/icon/icon@2x.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-1792h~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-1792h~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-2436h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-2436h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-2688h~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-2688h~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-568h@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-568h@2x~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-667h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-667h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-736h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape-1792h~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Landscape-1792h~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape-2436h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Landscape-2436h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape-2688h~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Landscape-2688h~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Landscape-736h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Landscape@2x~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Landscape@~ipadpro.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Landscape~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Portrait@2x~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Portrait@~ipadpro.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default-Portrait~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default@2x~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default@2x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default@2x~universal~anyany.png -------------------------------------------------------------------------------- /resources/ios/splash/Default~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/ios/splash/Default~iphone.png -------------------------------------------------------------------------------- /resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/resources/splash.png -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | {{ p.title }} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | {{ p.title }} 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import { StatusBar, Style as StatusBarStyle } from '@capacitor/status-bar'; 3 | import {Platform} from '@ionic/angular'; 4 | import { Storage } from '@ionic/storage-angular'; 5 | 6 | 7 | @Component({ 8 | selector: 'app-root', 9 | templateUrl: 'app.component.html', 10 | }) 11 | export class AppComponent { 12 | public appPages = [ 13 | { 14 | title: 'Dashboard', 15 | url: '/home', 16 | icon: 'home', 17 | new: false, 18 | }, 19 | { 20 | title: 'Instances', 21 | url: '/instances', 22 | icon: 'server', 23 | new: false, 24 | }, 25 | /* { 26 | title: 'Bare Metal', 27 | url: '/bmaas', 28 | icon: 'hdd', 29 | new: false, 30 | },*/ 31 | // { 32 | // title: 'Object Storage', 33 | // url: '/buckets', 34 | // icon: 'database', 35 | // new: true, 36 | // }, 37 | { 38 | title: 'Billing', 39 | url: '/billing', 40 | icon: 'chart-line', 41 | new: false, 42 | }, 43 | ]; 44 | 45 | public appPagesFooter = [ 46 | { 47 | title: 'Settings', 48 | url: '/settings', 49 | icon: 'cog', 50 | }, 51 | { 52 | title: 'About', 53 | url: '/about', 54 | icon: 'life-ring', 55 | }, 56 | ]; 57 | 58 | constructor( 59 | private platform: Platform, 60 | private storage: Storage 61 | ) { 62 | this.initializeApp(); 63 | } 64 | 65 | async ngOnInit() { 66 | await this.storage.create(); 67 | } 68 | 69 | initializeApp(): void { 70 | this.platform.ready().then(() => { 71 | StatusBar.setStyle({style: StatusBarStyle.Light}); 72 | }); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { HttpClientModule } from '@angular/common/http'; 2 | import { NgModule } from "@angular/core"; 3 | import { BrowserModule } from "@angular/platform-browser"; 4 | import { RouteReuseStrategy } from "@angular/router"; 5 | import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; 6 | import { library } from "@fortawesome/fontawesome-svg-core"; 7 | import { fas } from "@fortawesome/free-solid-svg-icons"; 8 | import { IonicModule, IonicRouteStrategy, Platform } from "@ionic/angular"; 9 | import { IonicStorageModule } from "@ionic/storage-angular"; 10 | 11 | import { AppRoutingModule } from "./app-routing.module"; 12 | import { AppComponent } from "./app.component"; 13 | 14 | @NgModule({ 15 | declarations: [AppComponent], 16 | imports: [ 17 | BrowserModule, 18 | IonicModule.forRoot(), 19 | IonicStorageModule.forRoot(), 20 | AppRoutingModule, 21 | FontAwesomeModule, 22 | HttpClientModule 23 | ], 24 | providers: [ 25 | ScreenOrientation, 26 | { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, 27 | ], 28 | bootstrap: [AppComponent] 29 | }) 30 | export class AppModule { 31 | constructor() { 32 | library.add(fas); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/components/components.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { RouterModule } from "@angular/router"; 5 | import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; 6 | import { IonicModule } from "@ionic/angular"; 7 | 8 | import { PipesModule } from "../pipes/pipes.module"; 9 | 10 | import { ErrorComponent } from "./error/error.component"; 11 | import { GraphComponent } from "./graph/graph.component"; 12 | import { ListComponent } from "./list/list.component"; 13 | import { LoaderComponent } from "./loader/loader.component"; 14 | 15 | @NgModule({ 16 | imports: [ 17 | CommonModule, 18 | FormsModule, 19 | IonicModule, 20 | FontAwesomeModule, 21 | PipesModule, 22 | RouterModule, 23 | ], 24 | declarations: [ 25 | GraphComponent, 26 | LoaderComponent, 27 | ErrorComponent, 28 | ListComponent, 29 | ], 30 | exports: [LoaderComponent, GraphComponent, ErrorComponent, ListComponent], 31 | }) 32 | export class ComponentsModule {} 33 | -------------------------------------------------------------------------------- /src/app/components/error/error.component.html: -------------------------------------------------------------------------------- 1 |
An error occurred, couldn't load data
2 | -------------------------------------------------------------------------------- /src/app/components/error/error.component.scss: -------------------------------------------------------------------------------- 1 | .light { 2 | padding: 2rem 1rem; 3 | text-align: center; 4 | color: white; 5 | } 6 | 7 | .dark { 8 | padding: 2rem 1rem; 9 | text-align: center; 10 | color: black; 11 | } 12 | -------------------------------------------------------------------------------- /src/app/components/error/error.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { ErrorComponent } from "./error.component"; 5 | 6 | describe("ErrorComponent", () => { 7 | let component: ErrorComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ErrorComponent], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(ErrorComponent); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/components/error/error.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-error", 5 | templateUrl: "./error.component.html", 6 | styleUrls: ["./error.component.scss"], 7 | }) 8 | export class ErrorComponent implements OnInit { 9 | @Input() variant = "dark"; 10 | 11 | constructor() {} 12 | 13 | ngOnInit() {} 14 | } 15 | -------------------------------------------------------------------------------- /src/app/components/graph/graph.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | {{ 5 | organizationName 6 | }} 7 | {{ projectName }} 8 |
9 |
10 | Current 11 |
12 | {{ (values[values.length - 1] || "0.00 ") + currency }} 13 |
14 |
15 |
16 | No data 17 |
18 |
19 | 20 | 21 |
22 | -------------------------------------------------------------------------------- /src/app/components/graph/graph.component.scss: -------------------------------------------------------------------------------- 1 | .header { 2 | &-left { 3 | display: flex; 4 | align-items: center; 5 | gap: 4px; 6 | margin-bottom: 1.25rem; 7 | color: white; 8 | font-weight: 300; 9 | font-size: 0.9rem; 10 | padding: 0.25rem 0.5rem; 11 | float: left; 12 | overflow: hidden; 13 | max-width: 50%; 14 | 15 | &-organization { 16 | font-weight: 500; 17 | } 18 | } 19 | 20 | &-right { 21 | color: white; 22 | font-size: 0.9rem; 23 | font-weight: 300; 24 | display: inline-block; 25 | margin-bottom: 1.25rem; 26 | float: right; 27 | 28 | &-amount { 29 | display: inline-block; 30 | background: white; 31 | color: black; 32 | border-radius: 10000px; 33 | padding: 0.25rem 0.5rem; 34 | } 35 | } 36 | } 37 | 38 | .no-data { 39 | height: 5vh; 40 | display: block; 41 | color: white; 42 | } 43 | 44 | fa-icon { 45 | padding: 0 0.25rem; 46 | } 47 | -------------------------------------------------------------------------------- /src/app/components/graph/graph.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { GraphComponent } from "./graph.component"; 5 | 6 | describe("GraphComponent", () => { 7 | let component: GraphComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [GraphComponent], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(GraphComponent); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/components/list/list.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 |
17 |
18 | 19 | os 27 | 28 | 29 |

{{ get(data, title) || title }}

30 |

{{ get(data, subTitle) || subTitle }}

31 |
32 | 33 |
34 | {{ data.area || "" }} 35 | area 40 |
41 |
42 |
43 |
44 |
45 | -------------------------------------------------------------------------------- /src/app/components/list/list.component.scss: -------------------------------------------------------------------------------- 1 | h2 { 2 | display: inline-block; 3 | vertical-align: middle; 4 | color: var(--ion-color-primary); 5 | } 6 | 7 | .img-os { 8 | height: 100%; 9 | width: auto; 10 | } 11 | 12 | ion-note { 13 | img { 14 | width: 20px; 15 | } 16 | } 17 | 18 | ion-label { 19 | margin-left: 0.5rem; 20 | } 21 | 22 | ion-avatar { 23 | margin-right: 0.25rem; 24 | } 25 | 26 | .background-white { 27 | --background: white; 28 | } 29 | 30 | .background-grey { 31 | --background: var(--ion-color-light); 32 | } 33 | 34 | .note-end { 35 | text-transform: uppercase; 36 | font-size: 0.8rem; 37 | 38 | img { 39 | margin-left: 0.5rem; 40 | } 41 | } 42 | 43 | .state { 44 | margin-right: 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/app/components/list/list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { ListComponent } from "./list.component"; 5 | 6 | describe("ListComponent", () => { 7 | let component: ListComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ListComponent], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(ListComponent); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/components/list/list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-list", 5 | templateUrl: "./list.component.html", 6 | styleUrls: ["./list.component.scss"], 7 | }) 8 | export class ListComponent implements OnInit { 9 | @Input() dataList: any; 10 | 11 | @Input() title: string; 12 | @Input() subTitle: string; 13 | 14 | @Input() route: string; 15 | 16 | @Input() hasState: boolean; 17 | @Input() stateVariableName: string; 18 | 19 | @Input() hasAvatar: boolean; 20 | @Input() avatarVariableName: string; 21 | 22 | constructor() {} 23 | 24 | ngOnInit() {} 25 | 26 | public get = (obj, path, defaultReturn = undefined) => { 27 | const getValue = path.split(".").reduce((acc, key) => acc && acc[key], obj); 28 | if (getValue === undefined) { 29 | return defaultReturn; 30 | } 31 | 32 | return getValue; 33 | }; 34 | 35 | public setState(state): string { 36 | switch (state) { 37 | case "stopped": 38 | return "#B2B6C3"; 39 | case "running": 40 | return "#30D1AD"; 41 | case "stopping": 42 | return "#3F6ED8"; 43 | case "starting": 44 | return "#3F6ED8"; 45 | default: 46 | return "#B2B6C3"; 47 | } 48 | } 49 | 50 | public setClass(state): string { 51 | switch (state) { 52 | case "stopped": 53 | return "state"; 54 | case "running": 55 | return "state"; 56 | case "stopping": 57 | return "blinker"; 58 | case "starting": 59 | return "blinker"; 60 | default: 61 | return "state"; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/app/components/loader/loader.component.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/app/components/loader/loader.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/app/components/loader/loader.component.scss -------------------------------------------------------------------------------- /src/app/components/loader/loader.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { LoaderComponent } from "./loader.component"; 5 | 6 | describe("LoaderComponent", () => { 7 | let component: LoaderComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [LoaderComponent], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(LoaderComponent); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/components/loader/loader.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-loader", 5 | templateUrl: "./loader.component.html", 6 | styleUrls: ["./loader.component.scss"], 7 | }) 8 | export class LoaderComponent implements OnInit { 9 | @Input() color: string; 10 | 11 | constructor() {} 12 | 13 | ngOnInit() {} 14 | } 15 | -------------------------------------------------------------------------------- /src/app/guards/double-auth/double-auth.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject, waitForAsync } from "@angular/core/testing"; 2 | 3 | import { DoubleAuthGuard } from "./double-auth.guard"; 4 | 5 | describe("DoubleAuthGuard", () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [DoubleAuthGuard], 9 | }); 10 | }); 11 | 12 | it("should ...", inject([DoubleAuthGuard], (guard: DoubleAuthGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /src/app/guards/double-auth/double-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { 3 | ActivatedRouteSnapshot, 4 | Router, 5 | CanActivate, 6 | RouterStateSnapshot, 7 | } from "@angular/router"; 8 | import { Observable } from "rxjs"; 9 | 10 | import { NavParamsService } from "../../services/nav/nav-params.service"; 11 | 12 | @Injectable({ 13 | providedIn: "root", 14 | }) 15 | export class DoubleAuthGuard implements CanActivate { 16 | constructor(private router: Router, private navParams: NavParamsService) {} 17 | 18 | canActivate( 19 | next: ActivatedRouteSnapshot, 20 | state: RouterStateSnapshot 21 | ): boolean | Observable | Promise { 22 | return new Promise((resolve, reject) => { 23 | const params = this.navParams.getParams(); 24 | if (params) { 25 | if (params.email && params.password) { 26 | resolve(true); 27 | } else { 28 | this.router.navigate(["login"]); 29 | resolve(false); 30 | } 31 | } else { 32 | this.router.navigate(["login"]); 33 | resolve(false); 34 | } 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/app/guards/home/home.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject, waitForAsync } from "@angular/core/testing"; 2 | 3 | import { HomeGuard } from "./home.guard"; 4 | 5 | describe("AuthGuard", () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [HomeGuard], 9 | }); 10 | }); 11 | 12 | it("should ...", inject([HomeGuard], (guard: HomeGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /src/app/guards/home/home.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { 3 | ActivatedRouteSnapshot, 4 | RouterStateSnapshot, 5 | CanActivate, 6 | Router, 7 | } from "@angular/router"; 8 | import { Storage } from "@ionic/storage-angular"; 9 | import { Observable } from "rxjs"; 10 | 11 | @Injectable({ 12 | providedIn: "root", 13 | }) 14 | export class HomeGuard implements CanActivate { 15 | constructor(private storage: Storage, private router: Router) {} 16 | 17 | canActivate( 18 | next: ActivatedRouteSnapshot, 19 | state: RouterStateSnapshot 20 | ): boolean | Observable | Promise { 21 | return new Promise(async (resolve, reject) => { 22 | const jwt = await this.storage.get("jwt"); 23 | const currentOrganization = await this.storage.get("currentOrganization"); 24 | const currentProject = await this.storage.get("currentProject"); 25 | if (!jwt || !currentOrganization || !currentProject) { 26 | await this.storage.clear(); 27 | this.router.navigate(["login"]); 28 | console.warn("HOME GUARD NOT VALIDATED"); 29 | resolve(false); 30 | } 31 | resolve(true); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/guards/login/login.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject, waitForAsync } from "@angular/core/testing"; 2 | 3 | import { LoginGuard } from "./login.guard"; 4 | 5 | describe("LoginGuard", () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [LoginGuard], 9 | }); 10 | }); 11 | 12 | it("should ...", inject([LoginGuard], (guard: LoginGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /src/app/guards/login/login.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { 3 | ActivatedRouteSnapshot, 4 | CanActivate, 5 | Router, 6 | RouterStateSnapshot, 7 | UrlTree, 8 | } from "@angular/router"; 9 | import { Storage } from "@ionic/storage-angular"; 10 | import { Observable } from "rxjs"; 11 | 12 | import { NavParamsService } from "../../services/nav/nav-params.service"; 13 | 14 | @Injectable({ 15 | providedIn: "root", 16 | }) 17 | export class LoginGuard implements CanActivate { 18 | constructor( 19 | private router: Router, 20 | private navParams: NavParamsService, 21 | private storage: Storage 22 | ) {} 23 | 24 | canActivate( 25 | next: ActivatedRouteSnapshot, 26 | state: RouterStateSnapshot 27 | ): boolean | Observable | Promise { 28 | return new Promise((resolve, reject) => { 29 | this.storage.get("jwt").then((val) => { 30 | if (val !== null) { 31 | this.router.navigate(["home"]); 32 | resolve(false); 33 | } else { 34 | resolve(true); 35 | } 36 | }); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/helpers/mergeZones.ts: -------------------------------------------------------------------------------- 1 | export const mergeZones = (zonesValue: any[]): T[] => { 2 | return [].concat(...zonesValue); 3 | } 4 | -------------------------------------------------------------------------------- /src/app/pages/about/about.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { AboutPage } from "./about.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: AboutPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | declarations: [AboutPage], 24 | }) 25 | export class AboutPageModule {} 26 | -------------------------------------------------------------------------------- /src/app/pages/about/about.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | About 7 | 8 | 9 | 10 | 11 |
12 |

Welcome on Scaleway Manager!

13 |

Here is a list of questions/answers that might help you:

14 | 15 |
How to connect?
16 |

You need a Scaleway account.

17 | 18 |
I'm having an issue, how to report it?
19 |

20 | At the bottom of this page you have a mail icon, tap on it and write me 21 | what's wrong. 22 |

23 | 24 |
Is it an official application published by Scaleway?
25 |

Absolutely not! This is an Open Source Project on GitHub.

26 | 27 |
Is this app free and without ads?
28 |

This application is totally free and without any advertising.

29 | 30 |
Who created this app?
31 |

32 | I'm only one developer, you can found me on Twitter: 33 | 34 |

35 | 36 |
What about our data/privacy?
37 |

38 | I do not sell or use your data at any moment. I just use Scaleway API to 39 | allow you to connect, get your servers, start them, ect. Also 40 | this project is Open Source on GitHub.

If you're still 41 | worried about your account security I recommend you to activate Two-Factor 42 | Authentication. 43 |

44 |
45 |
46 | -------------------------------------------------------------------------------- /src/app/pages/about/about.page.scss: -------------------------------------------------------------------------------- 1 | .about { 2 | &-content { 3 | background: white; 4 | padding: 1rem 1rem 1rem 1rem; 5 | } 6 | } 7 | 8 | ion-content { 9 | --background: white; 10 | } 11 | 12 | h5 { 13 | font-weight: bold; 14 | background: var(--ion-color-primary); 15 | background: linear-gradient( 16 | 141deg, 17 | #8800c8 40%, 18 | var(--ion-color-primary) 60% 19 | ); 20 | -webkit-background-clip: text; 21 | -webkit-text-fill-color: transparent; 22 | } 23 | 24 | h4 { 25 | font-weight: bold; 26 | } 27 | 28 | p { 29 | font-size: 0.9rem; 30 | margin-bottom: 2.5rem; 31 | margin-top: 0; 32 | } 33 | 34 | .twitter { 35 | color: #00acee; 36 | font-weight: bold; 37 | } 38 | -------------------------------------------------------------------------------- /src/app/pages/about/about.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { AboutPage } from "./about.page"; 5 | 6 | describe("AboutPage", () => { 7 | let component: AboutPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [AboutPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(AboutPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/about/about.page.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { StatusBar, Style as StatusBarStyle } from '@capacitor/status-bar'; 3 | import { Platform } from "@ionic/angular"; 4 | 5 | @Component({ 6 | selector: "app-about", 7 | templateUrl: "./about.page.html", 8 | styleUrls: ["./about.page.scss"], 9 | }) 10 | export class AboutPage implements OnInit { 11 | constructor( 12 | private platform: Platform 13 | ) {} 14 | 15 | ngOnInit() {} 16 | 17 | ionViewDidEnter() { 18 | StatusBar.setStyle({ style: StatusBarStyle.Light }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/pages/account/account.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; 6 | import { IonicModule } from "@ionic/angular"; 7 | 8 | import { ComponentsModule } from "../../components/components.module"; 9 | 10 | import { AccountPage } from "./account.page"; 11 | import { ChangeOrganizationPage } from "./change-organization/change-organization.page"; 12 | import { ChangeProjectPage } from "./change-project/change-project.page"; 13 | 14 | const routes: Routes = [ 15 | { 16 | path: "", 17 | component: AccountPage, 18 | }, 19 | ]; 20 | 21 | @NgModule({ 22 | imports: [ 23 | CommonModule, 24 | FormsModule, 25 | IonicModule, 26 | RouterModule.forChild(routes), 27 | FontAwesomeModule, 28 | ComponentsModule, 29 | ], 30 | declarations: [AccountPage, ChangeOrganizationPage, ChangeProjectPage] 31 | }) 32 | export class AccountPageModule {} 33 | -------------------------------------------------------------------------------- /src/app/pages/account/account.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { AccountPage } from "./account.page"; 5 | 6 | describe("AccountPage", () => { 7 | let component: AccountPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [AccountPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(AccountPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/account/change-organization/change-organization.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../components/components.module"; 8 | 9 | import { ChangeOrganizationPage } from "./change-organization.page"; 10 | 11 | const routes: Routes = [ 12 | { 13 | path: "", 14 | component: ChangeOrganizationPage, 15 | }, 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [ 20 | CommonModule, 21 | FormsModule, 22 | IonicModule, 23 | RouterModule.forChild(routes), 24 | ComponentsModule, 25 | ], 26 | declarations: [], 27 | }) 28 | export class ChangeOrganizationPageModule {} 29 | -------------------------------------------------------------------------------- /src/app/pages/account/change-organization/change-organization.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Change Organization 9 | 10 | Save 11 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 28 |
29 | 30 | {{ organization.name }} 31 | 32 | 33 |
34 |
35 |
36 |
37 |
38 | -------------------------------------------------------------------------------- /src/app/pages/account/change-organization/change-organization.page.scss: -------------------------------------------------------------------------------- 1 | ion-content { 2 | --background: white; 3 | } 4 | -------------------------------------------------------------------------------- /src/app/pages/account/change-organization/change-organization.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { ChangeOrganizationPage } from "./change-organization.page"; 5 | 6 | describe("ChangeOrganizationPage", () => { 7 | let component: ChangeOrganizationPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ChangeOrganizationPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(ChangeOrganizationPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/account/change-project/change-project.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../components/components.module"; 8 | 9 | import { ChangeProjectPage } from "./change-project.page"; 10 | 11 | const routes: Routes = [ 12 | { 13 | path: "", 14 | component: ChangeProjectPage, 15 | }, 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [ 20 | CommonModule, 21 | FormsModule, 22 | IonicModule, 23 | RouterModule.forChild(routes), 24 | ComponentsModule, 25 | ], 26 | declarations: [], 27 | }) 28 | export class ChangeProjectPageModule {} 29 | -------------------------------------------------------------------------------- /src/app/pages/account/change-project/change-project.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Change Project 9 | 10 | Save 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 23 |
24 | 25 | {{ project.name }} 26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 |
37 |

Oops!

38 |

Seems like you have no permissions for projects on this organization.

39 |
40 |
41 | -------------------------------------------------------------------------------- /src/app/pages/account/change-project/change-project.page.scss: -------------------------------------------------------------------------------- 1 | ion-content { 2 | --background: white; 3 | } 4 | -------------------------------------------------------------------------------- /src/app/pages/account/change-project/change-project.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { ChangeProjectPage } from "./change-project.page"; 5 | 6 | describe("ChangeProjectPage", () => { 7 | let component: ChangeProjectPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ChangeProjectPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(ChangeProjectPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/account/ssh-keys/add-ssh-key/add-ssh-key.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { AddSshKeyPage } from "./add-ssh-key.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: AddSshKeyPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | }) 24 | export class AddSshKeyPageModule {} 25 | -------------------------------------------------------------------------------- /src/app/pages/account/ssh-keys/add-ssh-key/add-ssh-key.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Add SSH Key 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | Add SSH Key 34 | 35 | -------------------------------------------------------------------------------- /src/app/pages/account/ssh-keys/add-ssh-key/add-ssh-key.page.scss: -------------------------------------------------------------------------------- 1 | ion-item { 2 | --background: white; 3 | margin: 0.75rem; 4 | border-radius: 3px; 5 | border: 1px solid lightgray; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/pages/account/ssh-keys/add-ssh-key/add-ssh-key.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { AddSshKeyPage } from "./add-ssh-key.page"; 5 | 6 | describe("AddSshKeyPage", () => { 7 | let component: AddSshKeyPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [AddSshKeyPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(AddSshKeyPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/account/ssh-keys/ssh-keys.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../components/components.module"; 8 | 9 | import { AddSshKeyPage } from "./add-ssh-key/add-ssh-key.page"; 10 | import { SshKeysPage } from "./ssh-keys.page"; 11 | 12 | const routes: Routes = [ 13 | { 14 | path: "", 15 | component: SshKeysPage, 16 | }, 17 | ]; 18 | 19 | @NgModule({ 20 | imports: [ 21 | CommonModule, 22 | FormsModule, 23 | IonicModule, 24 | RouterModule.forChild(routes), 25 | ComponentsModule, 26 | ], 27 | declarations: [SshKeysPage, AddSshKeyPage] 28 | }) 29 | export class SshKeysPageModule {} 30 | -------------------------------------------------------------------------------- /src/app/pages/account/ssh-keys/ssh-keys.page.scss: -------------------------------------------------------------------------------- 1 | .title { 2 | text-transform: uppercase; 3 | font-weight: 400; 4 | font-size: 0.9rem; 5 | } 6 | 7 | .description { 8 | &-left { 9 | color: #868686; 10 | margin-top: 0.2rem; 11 | float: left; 12 | } 13 | 14 | &-right { 15 | color: #868686; 16 | margin-top: 0.2rem; 17 | float: right; 18 | } 19 | } 20 | 21 | .text { 22 | background: white; 23 | padding: 1rem 1.2rem 1rem 1.2rem; 24 | } 25 | 26 | code { 27 | display: flex; 28 | position: relative; 29 | align-items: center; 30 | justify-content: center; 31 | text-align: center; 32 | background: #ededed; 33 | font-size: 0.7rem; 34 | padding: 0.25rem 0; 35 | } 36 | 37 | .no-ssh-keys { 38 | color: grey; 39 | text-align: center; 40 | width: 100%; 41 | ion-icon { 42 | font-size: 2.5rem; 43 | } 44 | p { 45 | text-transform: uppercase; 46 | font-weight: bold; 47 | font-size: 0.9rem; 48 | } 49 | } 50 | 51 | p { 52 | font-size: 0.9rem; 53 | } 54 | -------------------------------------------------------------------------------- /src/app/pages/account/ssh-keys/ssh-keys.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { SshKeysPage } from "./ssh-keys.page"; 5 | 6 | describe("SshKeysPage", () => { 7 | let component: SshKeysPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [SshKeysPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(SshKeysPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/account/tokens/tokens.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../components/components.module"; 8 | 9 | import { TokensPage } from "./tokens.page"; 10 | 11 | const routes: Routes = [ 12 | { 13 | path: "", 14 | component: TokensPage, 15 | }, 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [ 20 | CommonModule, 21 | FormsModule, 22 | IonicModule, 23 | RouterModule.forChild(routes), 24 | ComponentsModule, 25 | ], 26 | declarations: [TokensPage], 27 | }) 28 | export class TokensPageModule {} 29 | -------------------------------------------------------------------------------- /src/app/pages/account/tokens/tokens.page.scss: -------------------------------------------------------------------------------- 1 | .title { 2 | text-transform: uppercase; 3 | font-weight: 400; 4 | font-size: 0.9rem; 5 | } 6 | 7 | .text { 8 | background: white; 9 | padding: 1rem 1rem 1rem 1rem; 10 | } 11 | 12 | p { 13 | font-size: 0.9rem; 14 | } 15 | 16 | .description { 17 | &-left { 18 | color: #868686; 19 | margin-top: 0.2rem; 20 | float: left; 21 | font-size: 0.9rem; 22 | } 23 | 24 | &-right { 25 | color: #868686; 26 | margin-top: 0.2rem; 27 | float: right; 28 | font-size: 0.9rem; 29 | } 30 | } 31 | 32 | .no-tokens { 33 | color: grey; 34 | text-align: center; 35 | width: 100%; 36 | ion-icon { 37 | font-size: 2.5rem; 38 | } 39 | p { 40 | text-transform: uppercase; 41 | font-weight: bold; 42 | font-size: 0.9rem; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/app/pages/account/tokens/tokens.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { TokensPage } from "./tokens.page"; 5 | 6 | describe("TokensPage", () => { 7 | let component: TokensPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [TokensPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(TokensPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/auth/double-auth/double-auth.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { DoubleAuthPage } from "./double-auth.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: DoubleAuthPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | declarations: [DoubleAuthPage], 24 | }) 25 | export class DoubleAuthPageModule {} 26 | -------------------------------------------------------------------------------- /src/app/pages/auth/double-auth/double-auth.page.scss: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes breathing { 2 | 0% { 3 | -webkit-transform: scale(1); 4 | transform: scale(1); 5 | } 6 | 7 | 50% { 8 | -webkit-transform: scale(1.2); 9 | transform: scale(1.2); 10 | } 11 | 12 | 75% { 13 | -webkit-transform: scale(0.7); 14 | transform: scale(0.7); 15 | } 16 | 17 | 100% { 18 | -webkit-transform: scale(1); 19 | transform: scale(1); 20 | } 21 | } 22 | 23 | ion-icon { 24 | color: gray; 25 | height: 38px; 26 | } 27 | 28 | .login-header { 29 | ion-icon { 30 | font-size: 4rem; 31 | color: white; 32 | -webkit-animation: breathing 8s ease-out infinite normal; 33 | animation: breathing 8s ease-out infinite normal; 34 | } 35 | } 36 | 37 | ion-content { 38 | --background: url("/assets/img/background.svg") repeat 0 0, 39 | var(--ion-color-primary); 40 | } 41 | 42 | .login { 43 | &-header { 44 | display: flex; 45 | position: relative; 46 | align-items: center; 47 | justify-content: center; 48 | text-align: center; 49 | margin: 2.5rem 0 2rem 0; 50 | 51 | ion-icon { 52 | color: white; 53 | background: transparent; 54 | } 55 | } 56 | } 57 | 58 | /* OVERLOAD OF EXISTING CSS */ 59 | 60 | ion-input { 61 | --padding-start: 12px !important; 62 | background: var(--ion-color-light); 63 | height: 42px; 64 | } 65 | 66 | ion-card { 67 | background: white !important; 68 | } 69 | 70 | ion-item { 71 | --highlight-height: 0; 72 | --inner-padding-end: 0; 73 | } 74 | 75 | form { 76 | ion-icon { 77 | margin: 0; 78 | padding: 9px; 79 | background: var(--ion-color-light); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/app/pages/auth/double-auth/double-auth.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { DoubleAuthPage } from "./double-auth.page"; 5 | 6 | describe("DoubleAuthPage", () => { 7 | let component: DoubleAuthPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [DoubleAuthPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(DoubleAuthPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/auth/login/help/help.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { HelpPage } from "./help.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: HelpPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | }) 24 | export class HelpPageModule {} 25 | -------------------------------------------------------------------------------- /src/app/pages/auth/login/help/help.page.scss: -------------------------------------------------------------------------------- 1 | .help { 2 | &-content { 3 | background: white; 4 | padding: 1rem 1rem 1rem 1rem; 5 | } 6 | } 7 | 8 | ion-content { 9 | --background: white; 10 | } 11 | 12 | h5 { 13 | font-weight: bold; 14 | background: var(--ion-color-primary); 15 | background: linear-gradient( 16 | 141deg, 17 | #8800c8 40%, 18 | var(--ion-color-primary) 60% 19 | ); 20 | -webkit-background-clip: text; 21 | -webkit-text-fill-color: transparent; 22 | } 23 | 24 | h4 { 25 | font-weight: bold; 26 | } 27 | 28 | p { 29 | font-size: 0.9rem; 30 | margin-bottom: 2.5rem; 31 | margin-top: 0; 32 | } 33 | 34 | .twitter { 35 | color: #00acee; 36 | font-weight: bold; 37 | } 38 | -------------------------------------------------------------------------------- /src/app/pages/auth/login/help/help.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { HelpPage } from "./help.page"; 5 | 6 | describe("HelpPage", () => { 7 | let component: HelpPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [HelpPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(HelpPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/auth/login/help/help.page.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { StatusBar, Style as StatusBarStyle } from '@capacitor/status-bar'; 3 | import { ModalController, Platform } from "@ionic/angular"; 4 | 5 | 6 | 7 | @Component({ 8 | selector: "app-help", 9 | templateUrl: "./help.page.html", 10 | styleUrls: ["./help.page.scss"], 11 | }) 12 | export class HelpPage implements OnInit { 13 | constructor( 14 | private modalCtrl: ModalController, 15 | private platform: Platform, 16 | ) {} 17 | 18 | ngOnInit() {} 19 | 20 | ionViewDidEnter() { 21 | StatusBar.setStyle({ style: StatusBarStyle.Light }); 22 | } 23 | 24 | public async close() { 25 | await this.modalCtrl.dismiss({ 26 | dismissed: true, 27 | close: true, 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/pages/auth/login/login.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { HelpPage } from "./help/help.page"; 8 | import { LoginPage } from "./login.page"; 9 | 10 | const routes: Routes = [ 11 | { 12 | path: "", 13 | component: LoginPage, 14 | }, 15 | ]; 16 | 17 | @NgModule({ 18 | imports: [ 19 | CommonModule, 20 | FormsModule, 21 | IonicModule, 22 | RouterModule.forChild(routes), 23 | ], 24 | declarations: [LoginPage, HelpPage] 25 | }) 26 | export class LoginPageModule {} 27 | -------------------------------------------------------------------------------- /src/app/pages/auth/login/login.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { LoginPage } from "./login.page"; 5 | 6 | describe("LoginPage", () => { 7 | let component: LoginPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [LoginPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(LoginPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/billing/billing.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../components/components.module"; 8 | 9 | import { BillingPage } from "./billing.page"; 10 | 11 | const routes: Routes = [ 12 | { 13 | path: "", 14 | component: BillingPage, 15 | }, 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [ 20 | CommonModule, 21 | FormsModule, 22 | IonicModule, 23 | RouterModule.forChild(routes), 24 | ComponentsModule, 25 | ], 26 | declarations: [BillingPage], 27 | }) 28 | export class BillingPageModule {} 29 | -------------------------------------------------------------------------------- /src/app/pages/billing/billing.page.scss: -------------------------------------------------------------------------------- 1 | .information-title { 2 | &-content { 3 | text-transform: uppercase; 4 | font-weight: 400; 5 | } 6 | } 7 | 8 | .information-content { 9 | text-align: right; 10 | } 11 | 12 | span { 13 | display: block; 14 | } 15 | 16 | .price-ht { 17 | font-size: 0.9rem; 18 | margin-top: 0.2rem; 19 | color: dimgray; 20 | font-weight: lighter; 21 | } 22 | 23 | .date { 24 | font-size: 0.9rem; 25 | font-weight: lighter; 26 | margin-top: 0.2rem; 27 | color: dimgray; 28 | } 29 | 30 | .price { 31 | font-size: 1rem; 32 | } 33 | 34 | .title { 35 | text-transform: uppercase; 36 | font-weight: 400; 37 | font-size: 0.9rem; 38 | padding: 0.5rem 0.75rem; 39 | } 40 | 41 | .last-update { 42 | float: right; 43 | font-size: 0.8rem; 44 | } 45 | 46 | ion-item { 47 | --inner-padding-bottom: 0.75rem; 48 | --inner-padding-top: 0.75rem; 49 | background: white; 50 | } 51 | -------------------------------------------------------------------------------- /src/app/pages/billing/billing.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { BillingPage } from "./invoices.page"; 5 | 6 | describe("InvoicesPage", () => { 7 | let component: BillingPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [BillingPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(BillingPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/billing/billing.page.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import { StatusBar, Style as StatusBarStyle } from '@capacitor/status-bar'; 3 | 4 | import {BillingDto} from '../../services/billing/billing.dto'; 5 | import {BillingService} from '../../services/billing/billing.service'; 6 | 7 | @Component({ 8 | selector: 'app-billing', 9 | templateUrl: './billing.page.html', 10 | styleUrls: ['./billing.page.scss'], 11 | }) 12 | export class BillingPage { 13 | public billings: BillingDto[] = []; 14 | public currentInvoice: BillingDto; 15 | public isLoading = true; 16 | public billingError = false; 17 | 18 | constructor(private billingService: BillingService) { 19 | } 20 | 21 | ionViewDidEnter(): void { 22 | StatusBar.setStyle({style: StatusBarStyle.Light}); 23 | this.refresh() 24 | .catch(() => { 25 | this.billingError = true; 26 | }).finally(() => this.isLoading = false); 27 | } 28 | 29 | public doRefresh(refresher) { 30 | this.refresh() 31 | .then(() => { 32 | refresher.target.complete(); 33 | }) 34 | .catch((error) => { 35 | console.log(error); 36 | refresher.target.complete(); 37 | }); 38 | } 39 | 40 | private async refresh(): Promise { 41 | const billings = await this.billingService.getBillingList(100); 42 | this.currentInvoice = billings[0]; 43 | this.billings = billings.slice(1, billings.length); 44 | console.log(this.billings) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/app/pages/home/home.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { RouterModule } from "@angular/router"; 5 | import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; 6 | import { IonicModule } from "@ionic/angular"; 7 | 8 | import { ComponentsModule } from "../../components/components.module"; 9 | import { PipesModule } from "../../pipes/pipes.module"; 10 | 11 | import { HomePage } from "./home.page"; 12 | 13 | @NgModule({ 14 | imports: [ 15 | CommonModule, 16 | FormsModule, 17 | IonicModule, 18 | RouterModule.forChild([ 19 | { 20 | path: "", 21 | component: HomePage, 22 | }, 23 | ]), 24 | FontAwesomeModule, 25 | ComponentsModule, 26 | PipesModule, 27 | ], 28 | declarations: [HomePage], 29 | }) 30 | export class HomePageModule {} 31 | -------------------------------------------------------------------------------- /src/app/pages/home/home.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { HomePage } from "./home.page"; 5 | 6 | describe("HomePage", () => { 7 | let component: HomePage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [HomePage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(HomePage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/bmaas/bmaas.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../components/components.module"; 8 | import { PipesModule } from "../../../pipes/pipes.module"; 9 | 10 | import { BmaasPage } from "./bmaas.page"; 11 | 12 | const routes: Routes = [ 13 | { 14 | path: "", 15 | component: BmaasPage, 16 | }, 17 | ]; 18 | 19 | @NgModule({ 20 | imports: [ 21 | CommonModule, 22 | FormsModule, 23 | IonicModule, 24 | RouterModule.forChild(routes), 25 | ComponentsModule, 26 | PipesModule, 27 | ], 28 | declarations: [BmaasPage], 29 | }) 30 | export class BmaasPageModule {} 31 | -------------------------------------------------------------------------------- /src/app/pages/products/bmaas/bmaas.page.scss: -------------------------------------------------------------------------------- 1 | h2 { 2 | display: inline-block; 3 | vertical-align: middle; 4 | color: var(--ion-color-primary); 5 | } 6 | 7 | .img-os { 8 | height: 100%; 9 | width: auto; 10 | } 11 | 12 | ion-note { 13 | img { 14 | width: 20px; 15 | } 16 | } 17 | 18 | ion-label { 19 | margin-left: 0.5rem; 20 | } 21 | 22 | ion-avatar { 23 | margin-right: 0.25rem; 24 | } 25 | 26 | .background-white { 27 | --background: white; 28 | } 29 | 30 | .background-grey { 31 | --background: var(--ion-color-light); 32 | } 33 | -------------------------------------------------------------------------------- /src/app/pages/products/bmaas/bmaas.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { BmaasPage } from "./bmaas.page"; 5 | 6 | describe("BmaasPage", () => { 7 | let component: BmaasPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [BmaasPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(BmaasPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/bmaas/details/details.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../../components/components.module"; 8 | import { PipesModule } from "../../../../pipes/pipes.module"; 9 | 10 | import { DetailsPage } from "./details.page"; 11 | 12 | const routes: Routes = [ 13 | { 14 | path: "", 15 | component: DetailsPage, 16 | }, 17 | ]; 18 | 19 | @NgModule({ 20 | imports: [ 21 | CommonModule, 22 | FormsModule, 23 | IonicModule, 24 | RouterModule.forChild(routes), 25 | ComponentsModule, 26 | PipesModule, 27 | ], 28 | declarations: [DetailsPage] 29 | }) 30 | export class DetailsPageModule {} 31 | -------------------------------------------------------------------------------- /src/app/pages/products/bmaas/details/details.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | Details 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/app/pages/products/bmaas/details/details.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { DetailsPage } from "./details.page"; 5 | 6 | describe("DetailsPage", () => { 7 | let component: DetailsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [DetailsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(DetailsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/bmaas/details/details.page.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { ActivatedRoute } from "@angular/router"; 3 | import { 4 | AlertController, 5 | NavController, 6 | Platform, 7 | ToastController, 8 | } from "@ionic/angular"; 9 | 10 | import { BmaasService } from "../../../../services/bmaas/bmaas.service"; 11 | 12 | @Component({ 13 | selector: "app-details", 14 | templateUrl: "./details.page.html", 15 | styleUrls: ["./details.page.scss"], 16 | }) 17 | export class DetailsPage implements OnInit { 18 | public isLoading = true; 19 | public serverError = false; 20 | 21 | public server: any; 22 | 23 | constructor( 24 | private bmaasService: BmaasService, 25 | private toastCtrl: ToastController, 26 | private alertController: AlertController, 27 | private route: ActivatedRoute, 28 | private platform: Platform, 29 | private navCtrl: NavController 30 | ) {} 31 | 32 | ngOnInit() {} 33 | } 34 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/add-bucket/add-bucket.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { AddBucketPage } from "./add-bucket.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: AddBucketPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | }) 24 | export class AddBucketPageModule {} 25 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/add-bucket/add-bucket.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { AddBucketPage } from "./add-bucket.page"; 5 | 6 | describe("AddBucketPage", () => { 7 | let component: AddBucketPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [AddBucketPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(AddBucketPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/buckets.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { BucketsPage } from "./buckets.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: BucketsPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | declarations: [BucketsPage], 24 | }) 25 | export class BucketsPageModule {} 26 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/buckets.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { BucketsPage } from "./buckets.page"; 5 | 6 | describe("ObjectsPage", () => { 7 | let component: BucketsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [BucketsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(BucketsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/objects.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; 6 | import { IonicModule } from "@ionic/angular"; 7 | 8 | import { ComponentsModule } from "../../../../components/components.module"; 9 | import { PipesModule } from "../../../../pipes/pipes.module"; 10 | 11 | import { ObjectsPage } from "./objects.page"; 12 | import { ObjInfosPage } from "./options/obj-infos/obj-infos.page"; 13 | import { OptionsPage } from "./options/options.page"; 14 | 15 | const routes: Routes = [ 16 | { 17 | path: "", 18 | component: ObjectsPage, 19 | }, 20 | ]; 21 | 22 | @NgModule({ 23 | imports: [ 24 | CommonModule, 25 | FormsModule, 26 | IonicModule, 27 | RouterModule.forChild(routes), 28 | ComponentsModule, 29 | PipesModule, 30 | FontAwesomeModule, 31 | ], 32 | declarations: [ObjectsPage, OptionsPage, ObjInfosPage] 33 | }) 34 | export class ObjectsPageModule {} 35 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/objects.page.scss: -------------------------------------------------------------------------------- 1 | ion-content { 2 | --background: white; 3 | } 4 | 5 | .bucket-empty { 6 | color: grey; 7 | text-align: center; 8 | width: 100%; 9 | ion-icon { 10 | font-size: 2.5rem; 11 | } 12 | p { 13 | text-transform: uppercase; 14 | font-weight: bold; 15 | font-size: 0.9rem; 16 | } 17 | } 18 | 19 | ion-label { 20 | h3 { 21 | font-size: 0.8rem; 22 | } 23 | p { 24 | font-size: 0.75rem; 25 | } 26 | } 27 | 28 | fa-icon { 29 | width: 25px; 30 | text-align: center; 31 | } 32 | 33 | ion-title { 34 | --color: white; 35 | } 36 | 37 | fa-icon { 38 | font-size: 1.75rem; 39 | color: var(--ion-color-primary-tint); 40 | } 41 | 42 | .icon-snow { 43 | color: var(--ion-color-tertiary); 44 | margin-right: 0.5rem; 45 | font-size: 1rem; 46 | } 47 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/objects.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { ObjectsPage } from "./objects.page"; 5 | 6 | describe("ObjectsPage", () => { 7 | let component: ObjectsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ObjectsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(ObjectsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/obj-infos/obj-infos.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; 6 | import { IonicModule } from "@ionic/angular"; 7 | 8 | import { ObjInfosPage } from "./obj-infos.page"; 9 | 10 | const routes: Routes = [ 11 | { 12 | path: "", 13 | component: ObjInfosPage, 14 | }, 15 | ]; 16 | 17 | @NgModule({ 18 | imports: [ 19 | CommonModule, 20 | FormsModule, 21 | IonicModule, 22 | RouterModule.forChild(routes), 23 | ], 24 | }) 25 | export class ObjInfosPageModule {} 26 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/obj-infos/obj-infos.page.scss: -------------------------------------------------------------------------------- 1 | .file-header { 2 | background: white; 3 | border-radius: 1000px; 4 | text-align: center; 5 | padding: 1.5rem; 6 | width: 100px; 7 | height: 100px; 8 | margin: 1rem auto; 9 | display: flex; 10 | position: relative; 11 | align-items: center; 12 | justify-content: center; 13 | 14 | &-title { 15 | text-align: center; 16 | font-weight: bold; 17 | font-size: 1.1rem; 18 | color: var(--ion-color-dark); 19 | margin-bottom: 2rem; 20 | } 21 | } 22 | 23 | .information { 24 | &-title { 25 | font-weight: bold; 26 | color: #868686; 27 | text-transform: uppercase; 28 | font-size: 0.7rem; 29 | } 30 | 31 | &-header { 32 | text-transform: uppercase; 33 | padding: 0.25rem 1rem; 34 | font-size: 0.8rem; 35 | } 36 | 37 | &-content { 38 | text-transform: uppercase; 39 | display: flex; 40 | align-items: center; 41 | justify-content: center; 42 | 43 | ion-button { 44 | width: 8rem; 45 | margin: 0.5rem 0; 46 | font-size: 0.9rem; 47 | --border-radius: 6px; 48 | } 49 | 50 | img { 51 | width: 20px; 52 | margin-right: 0.5rem; 53 | } 54 | } 55 | } 56 | 57 | fa-icon { 58 | color: var(--ion-color-primary-tint); 59 | } 60 | 61 | .icon-snow { 62 | color: var(--ion-color-tertiary); 63 | margin-right: 0.5rem; 64 | } 65 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/obj-infos/obj-infos.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { ObjInfosPage } from "./obj-infos.page"; 5 | 6 | describe("ObjInfosPage", () => { 7 | let component: ObjInfosPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ObjInfosPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(ObjInfosPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/obj-infos/obj-infos.page.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { ModalController, NavParams } from "@ionic/angular"; 3 | 4 | @Component({ 5 | selector: "app-obj-infos", 6 | templateUrl: "./obj-infos.page.html", 7 | styleUrls: ["./obj-infos.page.scss"], 8 | }) 9 | export class ObjInfosPage implements OnInit { 10 | public object: any = null; 11 | public region: string = null; 12 | 13 | constructor( 14 | private modalCtrl: ModalController, 15 | private navParams: NavParams 16 | ) { 17 | this.object = this.navParams.get("object"); 18 | this.region = this.navParams.get("region"); 19 | } 20 | 21 | ngOnInit() {} 22 | 23 | public async close() { 24 | await this.modalCtrl.dismiss({ 25 | dismissed: true, 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/options.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { OptionsPage } from "./options.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: OptionsPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | }) 24 | export class OptionsPageModule {} 25 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/options.page.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | More info 11 | 14 | Send to S3 Glacier 17 | Edit name 20 | Delete 28 | 29 | 30 | 31 | More info 34 | 35 | 38 | Edit name 41 | Delete 49 | 50 | -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/options.page.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/app/pages/products/buckets/objects/options/options.page.scss -------------------------------------------------------------------------------- /src/app/pages/products/buckets/objects/options/options.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { OptionsPage } from "./options.page"; 5 | 6 | describe("OptionsPage", () => { 7 | let component: OptionsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [OptionsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(OptionsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/instances/details/details.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../../components/components.module"; 8 | import { PipesModule } from "../../../../pipes/pipes.module"; 9 | 10 | import { DetailsPage } from "./details.page"; 11 | 12 | const routes: Routes = [ 13 | { 14 | path: "", 15 | component: DetailsPage, 16 | }, 17 | ]; 18 | 19 | @NgModule({ 20 | imports: [ 21 | CommonModule, 22 | FormsModule, 23 | IonicModule, 24 | RouterModule.forChild(routes), 25 | PipesModule, 26 | ComponentsModule, 27 | ], 28 | declarations: [DetailsPage] 29 | }) 30 | export class DetailsPageModule {} 31 | -------------------------------------------------------------------------------- /src/app/pages/products/instances/details/details.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { DetailsPage } from "./details.page"; 5 | 6 | describe("DetailsPage", () => { 7 | let component: DetailsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [DetailsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(DetailsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/products/instances/instances.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { ComponentsModule } from "../../../components/components.module"; 8 | import { PipesModule } from "../../../pipes/pipes.module"; 9 | 10 | import { InstancesPage } from "./instances.page"; 11 | 12 | const routes: Routes = [ 13 | { 14 | path: "", 15 | component: InstancesPage, 16 | }, 17 | ]; 18 | 19 | @NgModule({ 20 | imports: [ 21 | CommonModule, 22 | FormsModule, 23 | IonicModule, 24 | RouterModule.forChild(routes), 25 | PipesModule, 26 | ComponentsModule, 27 | ], 28 | declarations: [InstancesPage], 29 | }) 30 | export class InstancesPageModule {} 31 | -------------------------------------------------------------------------------- /src/app/pages/products/instances/instances.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Instances 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 29 | 30 |
34 | no-server 35 |

No server available

36 | It is possible that you don't have resources permissions on this 38 | organization 40 |
41 |
42 |
43 | -------------------------------------------------------------------------------- /src/app/pages/products/instances/instances.page.scss: -------------------------------------------------------------------------------- 1 | h2 { 2 | display: inline-block; 3 | vertical-align: middle; 4 | color: var(--ion-color-primary); 5 | } 6 | 7 | .img-os { 8 | height: 100%; 9 | width: auto; 10 | } 11 | 12 | ion-note { 13 | img { 14 | width: 20px; 15 | } 16 | } 17 | 18 | ion-label { 19 | margin-left: 0.5rem; 20 | } 21 | 22 | ion-avatar { 23 | margin-right: 0.25rem; 24 | } 25 | 26 | .background-white { 27 | --background: white; 28 | } 29 | 30 | .background-grey { 31 | --background: var(--ion-color-light); 32 | } 33 | -------------------------------------------------------------------------------- /src/app/pages/products/instances/instances.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { InstancesPage } from "./instances.page"; 5 | 6 | describe("InstancesPage", () => { 7 | let component: InstancesPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [InstancesPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(InstancesPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pages/settings/settings.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { Routes, RouterModule } from "@angular/router"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { SettingsPage } from "./settings.page"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | component: SettingsPage, 13 | }, 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild(routes), 22 | ], 23 | declarations: [SettingsPage], 24 | }) 25 | export class SettingsPageModule {} 26 | -------------------------------------------------------------------------------- /src/app/pages/settings/settings.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Settings 7 | 8 | Save 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | Dashboard 19 | 20 | 21 |
22 | {{ instancesToDisplay }} 23 | 29 |
30 | Instances to display 31 |
32 |
33 |
34 | 35 | 39 |
40 | -------------------------------------------------------------------------------- /src/app/pages/settings/settings.page.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | display: flex; 3 | align-content: center; 4 | align-items: center; 5 | justify-content: center; 6 | margin-top: 1rem; 7 | opacity: 0.6; 8 | img { 9 | width: 25px; 10 | } 11 | h2 { 12 | color: var(--ion-color-primary); 13 | margin: 0 0 0 0.5rem; 14 | } 15 | } 16 | 17 | small { 18 | display: block; 19 | width: 100%; 20 | text-align: center; 21 | margin-top: 0.5rem; 22 | opacity: 0.6; 23 | color: var(--ion-color-primary); 24 | } 25 | 26 | .item-right { 27 | display: flex; 28 | align-content: center; 29 | align-items: center; 30 | justify-content: center; 31 | } 32 | 33 | .label-right { 34 | margin-right: 0.5rem; 35 | color: var(--ion-color-medium); 36 | } 37 | -------------------------------------------------------------------------------- /src/app/pages/settings/settings.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 2 | import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; 3 | 4 | import { SettingsPage } from "./settings.page"; 5 | 6 | describe("SettingsPage", () => { 7 | let component: SettingsPage; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(waitForAsync(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [SettingsPage], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | }).compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(SettingsPage); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it("should create", () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/pipes/billing-state-icon/billing-state-icon.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { BillingStateIconPipe } from "./billing-state-icon.pipe"; 2 | 3 | describe("BillingStateIconPipe", () => { 4 | it("create an instance", () => { 5 | const pipe = new BillingStateIconPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/pipes/billing-state-icon/billing-state-icon.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | 3 | @Pipe({ 4 | name: "billingStateIcon", 5 | }) 6 | export class BillingStateIconPipe implements PipeTransform { 7 | transform(state: string) { 8 | state = state.toLowerCase(); 9 | 10 | let icon = "help"; 11 | const value = true; 12 | 13 | switch (value) { 14 | case state.indexOf("paid") !== -1: 15 | icon = "md-checkmark"; 16 | break; 17 | case state.indexOf("draft") !== -1: 18 | icon = "md-time"; 19 | break; 20 | case state.indexOf("stopped") !== -1: 21 | icon = "stopwatch"; 22 | break; 23 | case state.indexOf("Outdated") !== -1: 24 | icon = "md-time"; 25 | break; 26 | case state.indexOf("Incomplete") !== -1: 27 | icon = "close"; 28 | break; 29 | case state.indexOf("Issued") !== -1: 30 | icon = "md-time"; 31 | break; 32 | default: 33 | icon = "help"; 34 | } 35 | 36 | return icon; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/pipes/file-size/file-size.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { FileSizePipe } from "./file-size.pipe"; 2 | 3 | describe("FileSizePipe", () => { 4 | it("create an instance", () => { 5 | const pipe = new FileSizePipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/pipes/file-size/file-size.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | 3 | @Pipe({ 4 | name: "fileSize", 5 | }) 6 | export class FileSizePipe implements PipeTransform { 7 | private units = ["B", "kB", "MB", "GB", "TB", "PB"]; 8 | 9 | transform(bytes = 0, precision = 2): string { 10 | if (isNaN(parseFloat(String(bytes))) || !isFinite(bytes)) { 11 | return "?"; 12 | } 13 | 14 | let unit = 0; 15 | 16 | while (bytes >= 1024) { 17 | bytes /= 1024; 18 | unit++; 19 | } 20 | 21 | return Number(bytes).toFixed(+precision) + " " + this.units[unit]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/app/pipes/pipes.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from "@angular/common"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; 5 | import { IonicModule } from "@ionic/angular"; 6 | 7 | import { BillingStateIconPipe } from "./billing-state-icon/billing-state-icon.pipe"; 8 | import { FileSizePipe } from "./file-size/file-size.pipe"; 9 | import { ServerIconPipe } from "./server-icon/server-icon.pipe"; 10 | import { TotalVolumesSpacePipe } from "./total-volume-space/total-volumes-space.pipe"; 11 | import { ZoneFlagPipe } from "./zone-flag/zone-flag.pipe"; 12 | 13 | @NgModule({ 14 | imports: [CommonModule, FormsModule, IonicModule, FontAwesomeModule], 15 | declarations: [ 16 | ServerIconPipe, 17 | BillingStateIconPipe, 18 | TotalVolumesSpacePipe, 19 | FileSizePipe, 20 | ZoneFlagPipe, 21 | ], 22 | exports: [ 23 | ServerIconPipe, 24 | BillingStateIconPipe, 25 | TotalVolumesSpacePipe, 26 | FileSizePipe, 27 | ZoneFlagPipe, 28 | ], 29 | }) 30 | export class PipesModule {} 31 | -------------------------------------------------------------------------------- /src/app/pipes/server-icon/server-icon.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { ServerIconPipe } from "./server-icon.pipe"; 2 | 3 | describe("ServerIconPipe", () => { 4 | it("create an instance", () => { 5 | const pipe = new ServerIconPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/pipes/server-icon/server-icon.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | 3 | @Pipe({ 4 | name: "serverIcon", 5 | }) 6 | export class ServerIconPipe implements PipeTransform { 7 | private readonly serverOsList = [ 8 | "ubuntu", 9 | "arch", 10 | "debian", 11 | "fedora", 12 | "alpine", 13 | "gitlab", 14 | "openvpn", 15 | "centos", 16 | ]; 17 | 18 | transform(value: string) { 19 | if (value && value !== "") { 20 | const osName = value.toLowerCase(); 21 | 22 | let picturePath = "assets/img/server.svg"; 23 | this.serverOsList.map((os) => { 24 | if (osName.includes(os)) { 25 | picturePath = `assets/img/${os}.svg`; 26 | } 27 | }); 28 | 29 | return picturePath; 30 | } else { 31 | return "assets/img/server.svg"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/pipes/total-volume-space/total-volumes-space.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { TotalVolumesSpacePipe } from "./total-volumes-space.pipe"; 2 | 3 | describe("TotalVolumesSpacePipe", () => { 4 | it("create an instance", () => { 5 | const pipe = new TotalVolumesSpacePipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/pipes/total-volume-space/total-volumes-space.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | 3 | import { Volume } from "../../services/servers/server.dto"; 4 | 5 | @Pipe({ 6 | name: "totalVolumesSpace", 7 | }) 8 | export class TotalVolumesSpacePipe implements PipeTransform { 9 | transform(volumes: Volume[]): any { 10 | let size = 0; 11 | let i = -1; 12 | 13 | while (volumes[++i]) { 14 | size += volumes[i].size / 1000000000; 15 | } 16 | 17 | const str: string = size + "Go"; 18 | return str; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/pipes/zone-flag/zone-flag.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { ZoneFlagPipe } from "./zone-flag.pipe"; 2 | 3 | describe("ZoneFlagPipe", () => { 4 | it("create an instance", () => { 5 | const pipe = new ZoneFlagPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/pipes/zone-flag/zone-flag.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | 3 | @Pipe({ 4 | name: "zoneFlag", 5 | }) 6 | export class ZoneFlagPipe implements PipeTransform { 7 | transform(value: string): any { 8 | let picturePath: string; 9 | switch (true) { 10 | case value.includes("fr-par"): 11 | picturePath = "assets/img/france.svg"; 12 | break; 13 | case value.includes("nl-ams"): 14 | picturePath = "assets/img/netherlands.svg"; 15 | break; 16 | case value.includes("pl-waw"): 17 | picturePath = "assets/img/warsaw.svg"; 18 | break; 19 | default: 20 | picturePath = "assets/img/all.svg"; 21 | break; 22 | } 23 | 24 | return picturePath; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/app/services/api/api.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { ApiService } from "./api.service"; 4 | 5 | describe("ApiService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: ApiService = TestBed.get(ApiService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/billing/billing.dto.ts: -------------------------------------------------------------------------------- 1 | export interface BillingDto { 2 | total_untaxed: string; 3 | organization_name: string; 4 | due_date: string; 5 | total_tax: string; 6 | stop_date: string; 7 | issued_date: string; 8 | number: number; 9 | id: string; 10 | organization_id: string; 11 | currency: string; 12 | state: string; 13 | total_taxed: string; 14 | last_update: string; 15 | total_undiscounted: string; 16 | start_date: string; 17 | } 18 | -------------------------------------------------------------------------------- /src/app/services/billing/billing.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { BillingService } from "./billing.service"; 4 | 5 | describe("BillingService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: BillingService = TestBed.get(BillingService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/billing/billing.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Storage } from "@ionic/storage-angular"; 3 | 4 | import { ApiService } from "../api/api.service"; 5 | 6 | import { BillingDto } from "./billing.dto"; 7 | 8 | @Injectable({ 9 | providedIn: "root", 10 | }) 11 | export class BillingService { 12 | constructor(private api: ApiService, private storage: Storage) {} 13 | 14 | public async getBillingList(value: number): Promise { 15 | const ApiUrl = this.api.getApiUrl(); 16 | 17 | const organizationId = await this.storage.get("currentOrganization"); 18 | const result = await this.api.get<{ invoices: BillingDto[] }>( 19 | `${ApiUrl}/billing/v1/invoices?organization_id=${organizationId}&page=1&per_page=${value}` 20 | ); 21 | 22 | return result.invoices 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/services/bmaas/bmaas.dto.ts: -------------------------------------------------------------------------------- 1 | export interface BmaasDto { 2 | name: string; 3 | state: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/app/services/bmaas/bmaas.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { BmaasService } from "./bmaas.service"; 4 | 5 | describe("BmaasService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: BmaasService = TestBed.get(BmaasService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/bmaas/config.ts: -------------------------------------------------------------------------------- 1 | export const areas = ["fr-par-2"]; 2 | -------------------------------------------------------------------------------- /src/app/services/nav/nav-params.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { NavParamsService } from "./nav-params.service"; 4 | 5 | describe("NavParamsService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: NavParamsService = TestBed.get(NavParamsService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/nav/nav-params.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | 3 | @Injectable({ 4 | providedIn: "root", 5 | }) 6 | export class NavParamsService { 7 | params: any; 8 | 9 | constructor() {} 10 | 11 | public setParams(data) { 12 | this.params = data; 13 | } 14 | 15 | public getParams(): any { 16 | return this.params; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/services/object/config.ts: -------------------------------------------------------------------------------- 1 | export const zones = ["fr-par", "nl-ams", "pl-waw"]; 2 | -------------------------------------------------------------------------------- /src/app/services/object/object.dto.ts: -------------------------------------------------------------------------------- 1 | export interface BucketsInfosDto { 2 | current_size: number; 3 | current_objects: number; 4 | quota_size: number; 5 | quota_objects: number; 6 | quota_buckets: number; 7 | buckets: any; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/services/object/object.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { ObjectService } from "./object.service"; 4 | 5 | describe("ObjectService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: ObjectService = TestBed.get(ObjectService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/servers/actions.dto.ts: -------------------------------------------------------------------------------- 1 | export interface ActionsDto { 2 | task: Task; 3 | } 4 | 5 | export interface Task { 6 | description: string; 7 | href_from: string; 8 | id: string; 9 | progress: string; 10 | status: string; 11 | } 12 | -------------------------------------------------------------------------------- /src/app/services/servers/config.ts: -------------------------------------------------------------------------------- 1 | export const areas = ["fr-par-1", "fr-par-2", "nl-ams-1", "pl-waw-1"]; 2 | -------------------------------------------------------------------------------- /src/app/services/servers/servers.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { ServersService } from "./servers.service"; 4 | 5 | describe("ServersService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: ServersService = TestBed.get(ServersService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/user/account/account.dto.ts: -------------------------------------------------------------------------------- 1 | export interface UsersDto { 2 | user: UserDto; 3 | } 4 | 5 | export interface UserDto { 6 | created_at: string; 7 | mfa_enabled: boolean; 8 | email: string; 9 | first_name: string; 10 | account_root_user_id: string; 11 | last_name: string; 12 | updated_at: string; 13 | organizations: any; 14 | phone_number: string; 15 | roles: any; 16 | ssh_public_keys: any; 17 | } 18 | -------------------------------------------------------------------------------- /src/app/services/user/account/account.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { AccountService } from "./account.service"; 4 | 5 | describe("AccountService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: AccountService = TestBed.get(AccountService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/user/account/account.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {Storage} from "@ionic/storage-angular"; 3 | 4 | import {ApiService} from "../../api/api.service"; 5 | 6 | import {UserDto} from "./account.dto"; 7 | 8 | @Injectable({ 9 | providedIn: "root", 10 | }) 11 | export class AccountService { 12 | constructor(private api: ApiService, private storage: Storage) { 13 | } 14 | 15 | public async getUserData(): Promise { 16 | const iamUser = await this.storage.get("iam"); 17 | const result = await this.api.get( 18 | this.api.getAccountApiUrlV2() + "/users/" + iamUser.account_root_user_id 19 | ); 20 | 21 | return result; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/app/services/user/auth/auth.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { AuthService } from "./auth.service"; 4 | 5 | describe("AuthService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: AuthService = TestBed.get(AuthService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/user/project/project.dto.ts: -------------------------------------------------------------------------------- 1 | export interface ProjectsDto { 2 | projects: ProjectDto[]; 3 | } 4 | 5 | export interface ProjectDto { 6 | created_at: string; 7 | description: string; 8 | id: string; 9 | name: string; 10 | organization_id: string; 11 | updated_at: string; 12 | } 13 | -------------------------------------------------------------------------------- /src/app/services/user/project/project.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { ProjectService } from "./project.service"; 4 | 5 | describe("ProjectService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: ProjectService = TestBed.get(ProjectService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/user/project/ssh-key/ssh-keys.dto.ts: -------------------------------------------------------------------------------- 1 | export interface SshKeysDto { 2 | ssh_keys: SshKeysDto[]; 3 | } 4 | 5 | export interface SshKeysDto { 6 | created_at: string; 7 | creation_info: { 8 | address: string; 9 | user_agent: string; 10 | area_code: string; 11 | }; 12 | fingerprint: string; 13 | id: string; 14 | name: string; 15 | organization_id: string; 16 | project_id: string; 17 | public_key: string; 18 | updated_at: string; 19 | } 20 | -------------------------------------------------------------------------------- /src/app/services/user/project/ssh-key/ssh-keys.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { SshKeysService } from "./ssh-keys.service"; 4 | 5 | describe("SshKeysService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: SshKeysService = TestBed.get(SshKeysService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/services/user/project/ssh-key/ssh-keys.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | 3 | import { ApiService } from "../../../api/api.service"; 4 | import { ProjectService } from "../project.service"; 5 | 6 | import { SshKeysDto } from "./ssh-keys.dto"; 7 | 8 | @Injectable({ 9 | providedIn: "root", 10 | }) 11 | export class SshKeysService { 12 | constructor( 13 | private api: ApiService, 14 | private projectService: ProjectService 15 | ) {} 16 | 17 | public async getSShKeys() { 18 | try { 19 | const currentProject = await this.projectService.getCurrentProject(); 20 | const result = await this.api.get( 21 | `${this.api.getApiUrl()}/iam/v1alpha1/ssh-keys/?project_id=${ 22 | currentProject.id 23 | }` 24 | ); 25 | 26 | return result.ssh_keys; 27 | } catch (e) { 28 | throw e; 29 | } 30 | } 31 | 32 | public async addSShKey(sshKey: string) { 33 | try { 34 | const currentProject = await this.projectService.getCurrentProject(); 35 | await this.api.post(`${this.api.getApiUrl()}/iam/v1alpha1/ssh-keys`, { 36 | project_id: currentProject.id, 37 | public_key: sshKey, 38 | }); 39 | } catch (e) { 40 | throw e; 41 | } 42 | } 43 | 44 | public async deleteSShKey(sshKeyId: string) { 45 | try { 46 | await this.api.delete( 47 | `${this.api.getApiUrl()}/iam/v1alpha1/ssh-key/${sshKeyId}` 48 | ); 49 | } catch (e) { 50 | throw e; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app/services/user/project/tokens/tokens.dto.ts: -------------------------------------------------------------------------------- 1 | export interface TokensDto { 2 | api_keys: TokenDto[]; 3 | } 4 | 5 | export interface TokenDto { 6 | access_key: string; 7 | application_id: string; 8 | created_at: string; 9 | creation_ip: string; 10 | default_project_id: string; 11 | description: string; 12 | editable: boolean; 13 | expires_at: string; 14 | secret_key: string; 15 | updated_at: string; 16 | } 17 | -------------------------------------------------------------------------------- /src/app/services/user/project/tokens/tokens.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from "@angular/core/testing"; 2 | 3 | import { TokensService } from "./tokens.service"; 4 | 5 | describe("TokensService", () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it("should be created", () => { 9 | const service: TokensService = TestBed.get(TokensService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/assets/icon-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icon-background.png -------------------------------------------------------------------------------- /src/assets/icon-foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icon-foreground.png -------------------------------------------------------------------------------- /src/assets/icon-only.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icon-only.png -------------------------------------------------------------------------------- /src/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icon/favicon.png -------------------------------------------------------------------------------- /src/assets/icons/icon-128.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icons/icon-128.webp -------------------------------------------------------------------------------- /src/assets/icons/icon-192.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icons/icon-192.webp -------------------------------------------------------------------------------- /src/assets/icons/icon-256.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icons/icon-256.webp -------------------------------------------------------------------------------- /src/assets/icons/icon-48.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icons/icon-48.webp -------------------------------------------------------------------------------- /src/assets/icons/icon-512.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icons/icon-512.webp -------------------------------------------------------------------------------- /src/assets/icons/icon-72.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icons/icon-72.webp -------------------------------------------------------------------------------- /src/assets/icons/icon-96.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/icons/icon-96.webp -------------------------------------------------------------------------------- /src/assets/img/alpine.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/france.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/gitlab.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/img/key.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/img/netherlands.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/openvpn.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/warsaw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/splash-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/splash-dark.png -------------------------------------------------------------------------------- /src/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthprost/scaleway-manager/3ee5d0e59949f887ad898a05e6b9c0b769d9c0e4/src/assets/splash.png -------------------------------------------------------------------------------- /src/global.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/theming/ 2 | @import "~@ionic/angular/css/core.css"; 3 | @import "~@ionic/angular/css/normalize.css"; 4 | @import "~@ionic/angular/css/structure.css"; 5 | @import "~@ionic/angular/css/typography.css"; 6 | @import "~@ionic/angular/css/display.css"; 7 | @import "~@ionic/angular/css/padding.css"; 8 | @import "~@ionic/angular/css/float-elements.css"; 9 | @import "~@ionic/angular/css/text-alignment.css"; 10 | @import "~@ionic/angular/css/text-transformation.css"; 11 | @import "~@ionic/angular/css/flex-utils.css"; 12 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ionic App 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: "", 7 | frameworks: ["jasmine", "@angular-devkit/build-angular"], 8 | plugins: [ 9 | require("karma-jasmine"), 10 | require("karma-chrome-launcher"), 11 | require("karma-jasmine-html-reporter"), 12 | require("karma-coverage-istanbul-reporter"), 13 | require("@angular-devkit/build-angular/plugins/karma"), 14 | ], 15 | client: { 16 | clearContext: false, // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require("path").join(__dirname, "../coverage"), 20 | reports: ["html", "lcovonly", "text-summary"], 21 | fixWebpackSourcePaths: true, 22 | }, 23 | reporters: ["progress", "kjhtml"], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ["Chrome"], 29 | singleRun: false, 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from "@angular/core"; 2 | import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; 3 | 4 | import { AppModule } from "./app/app.module"; 5 | import { environment } from "./environments/environment"; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic() 12 | .bootstrapModule(AppModule) 13 | .catch((err) => console.log(err)); 14 | -------------------------------------------------------------------------------- /src/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "icons": [ 3 | { 4 | "src": "assets/icons/icon-48.webp", 5 | "type": "image/png", 6 | "sizes": "48x48", 7 | "purpose": "any maskable" 8 | }, 9 | { 10 | "src": "assets/icons/icon-72.webp", 11 | "type": "image/png", 12 | "sizes": "72x72", 13 | "purpose": "any maskable" 14 | }, 15 | { 16 | "src": "assets/icons/icon-96.webp", 17 | "type": "image/png", 18 | "sizes": "96x96", 19 | "purpose": "any maskable" 20 | }, 21 | { 22 | "src": "assets/icons/icon-128.webp", 23 | "type": "image/png", 24 | "sizes": "128x128", 25 | "purpose": "any maskable" 26 | }, 27 | { 28 | "src": "assets/icons/icon-192.webp", 29 | "type": "image/png", 30 | "sizes": "192x192", 31 | "purpose": "any maskable" 32 | }, 33 | { 34 | "src": "assets/icons/icon-256.webp", 35 | "type": "image/png", 36 | "sizes": "256x256", 37 | "purpose": "any maskable" 38 | }, 39 | { 40 | "src": "assets/icons/icon-512.webp", 41 | "type": "image/png", 42 | "sizes": "512x512", 43 | "purpose": "any maskable" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import "zone.js/testing"; 4 | import { getTestBed } from "@angular/core/testing"; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting, 8 | } from "@angular/platform-browser-dynamic/testing"; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting() 14 | ); 15 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "exclude": ["test.ts", "**/*.spec.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "types": ["jasmine", "node"] 6 | }, 7 | "files": ["test.ts", "zone-flags.ts", "polyfills.ts"], 8 | "include": ["**/*.spec.ts", "**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /src/zone-flags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prevents Angular change detection from 3 | * running with certain Web Component callbacks 4 | */ 5 | (window as any).__Zone_disable_customElements = true; 6 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts", 11 | "src/zone-flags.ts" 12 | ], 13 | "include": [ 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": false, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "sourceMap": true, 12 | "declaration": false, 13 | "downlevelIteration": true, 14 | "experimentalDecorators": true, 15 | "moduleResolution": "node", 16 | "importHelpers": true, 17 | "target": "ES2022", 18 | "module": "es2020", 19 | "lib": [ 20 | "es2018", 21 | "dom" 22 | ], 23 | "emitDecoratorMetadata": false, 24 | "useDefineForClassFields": false 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": false, 29 | "strictInputAccessModifiers": false, 30 | "strictTemplates": false, 31 | "fullTemplateTypeCheck": false, 32 | "strictDomLocalRefTypes": false, 33 | "strictDomEventTypes": false, 34 | "strictOutputEventTypes": false, 35 | "strictNullInputTypes": false, 36 | "strictAttributeTypes": false, 37 | "strictContextGenerics": false 38 | }, 39 | } 40 | --------------------------------------------------------------------------------