Skip to content

Commit

Permalink
Merge branch 'main' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
he3als committed Nov 17, 2024
2 parents 528761a + ba5d1cd commit 281fa9d
Show file tree
Hide file tree
Showing 28 changed files with 592 additions and 452 deletions.
35 changes: 21 additions & 14 deletions .github/workflows-disabled/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
name: Tests

on:
push:
branches:
- "develop"
- "1.0-develop"
pull_request:
branches:
- "develop"
- "1.0-develop"
#on:
#push:
#branches:
#- "dev"
#- "main"
#pull_request:
# branches:
#- "dev"
#- "main"

jobs:
tests:
name: Tests
runs-on: ubuntu-20.04
permissions:
contents: read
strategy:
fail-fast: false
matrix:
php: [8.1, 8.2]
database: ["mariadb:10.2", "mysql:8"]
#php: [8.2, 8.3]
php: [8.2]
database:
#- mariadb:10.5
#- mariadb:10.11
- mariadb:11.5
#- mysql:8
#- mysql:9
services:
database:
image: ${{ matrix.database }}
Expand All @@ -27,18 +35,17 @@ jobs:
MYSQL_DATABASE: testing
ports:
- 3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Code Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Get cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
!.env.example
.env*
.vagrant/
.vscode/
storage/framework/*
/.idea
/nbproject
Expand Down
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
}
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"prettier.endOfLine": "lf",
"editor.formatOnSave": true,
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}
402 changes: 239 additions & 163 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
"@codemirror/language-data": "^6.5.1",
"@codemirror/legacy-modes": "^6.4.0",
"@codemirror/lint": "^6.5.0",
"@codemirror/search": "^6.5.6",
"@codemirror/search": "^6.5.7",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.26.3",
"@eslint/compat": "^1.1.1",
"@eslint/compat": "^1.2.2",
"@fortawesome/fontawesome-svg-core": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
Expand All @@ -27,7 +27,7 @@
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@sentry/react": "^7.110.0",
"@sentry/react": "^7.120.0",
"@sentry/vite-plugin": "^2.16.1",
"@tanstack/react-virtual": "^3.2.1",
"@xterm/addon-fit": "^0.10.0",
Expand All @@ -41,12 +41,12 @@
"cmdk": "^1.0.0",
"copy-to-clipboard": "^3.3.3",
"date-fns": "^3.6.0",
"debounce": "^2.0.0",
"debounce": "^2.2.0",
"deepmerge-ts": "^7.1.0",
"easy-peasy": "^6.0.4",
"events": "^3.3.0",
"formik": "^2.4.5",
"framer-motion": "^11.0.28",
"framer-motion": "^11.11.11",
"globals": "^15.9.0",
"laravel-vite-plugin": "^1.0.2",
"million": "^3.0.6",
Expand All @@ -67,7 +67,7 @@
"tailwindcss-animate": "^1.0.7",
"turbo": "^2.0.14",
"uuid": "^9.0.1",
"vite": "^5.2.8",
"vite": "^5.4.11",
"yup": "^1.4.0"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import requestPasswordResetEmail from '@/api/auth/requestPasswordResetEmail';
import { httpErrorToHuman } from '@/api/http';

import useFlash from '@/plugins/useFlash';

import Logo from '../elements/PyroLogo';

interface Values {
Expand Down
34 changes: 17 additions & 17 deletions resources/scripts/components/dashboard/AccountApiContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { format } from 'date-fns';
import { useEffect, useState } from 'react';

Expand All @@ -15,8 +16,6 @@ import getApiKeys, { ApiKey } from '@/api/account/getApiKeys';

import { useFlashKey } from '@/plugins/useFlash';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

export default () => {
const [deleteIdentifier, setDeleteIdentifier] = useState('');
const [keys, setKeys] = useState<ApiKey[]>([]);
Expand Down Expand Up @@ -46,12 +45,12 @@ export default () => {
return (
<PageContentBlock title={'Account API'}>
{/* Flash messages will now appear at the top of the page */}
<FlashMessageRender byKey="account" />
<div className="md:flex flex-nowrap my-10 space-x-8">
<ContentBox title={'Create API Key'} className="flex-none w-full md:w-1/2">
<FlashMessageRender byKey='account' />
<div className='md:flex flex-nowrap my-10 space-x-8'>
<ContentBox title={'Create API Key'} className='flex-none w-full md:w-1/2'>
<CreateApiKeyForm onKeyCreated={(key) => setKeys((s) => [...s!, key])} />
</ContentBox>
<ContentBox title={'API Keys'} className="flex-1 overflow-hidden mt-8 md:mt-0">
<ContentBox title={'API Keys'} className='flex-1 overflow-hidden mt-8 md:mt-0'>
<SpinnerOverlay visible={loading} />
<Dialog.Confirm
title={'Delete API Key'}
Expand All @@ -63,29 +62,30 @@ export default () => {
All requests using the <Code>{deleteIdentifier}</Code> key will be invalidated.
</Dialog.Confirm>
{keys.length === 0 ? (
<p className="text-center text-sm text-gray-500">
<p className='text-center text-sm text-gray-500'>
{loading ? 'Loading...' : 'No API keys exist for this account.'}
</p>
) : (
keys.map((key) => (
<div key={key.identifier} className="flex flex-col mb-6 space-y-4">
<div className="flex items-center justify-between space-x-4 border border-gray-300 rounded-lg p-4 transition duration-200">
<div className="flex-1">
<p className="text-sm font-medium">{key.description}</p>
<p className="text-xs text-gray-500 uppercase">
Last used: {key.lastUsedAt ? format(key.lastUsedAt, 'MMM d, yyyy HH:mm') : 'Never'}
<div key={key.identifier} className='flex flex-col mb-6 space-y-4'>
<div className='flex items-center justify-between space-x-4 border border-gray-300 rounded-lg p-4 transition duration-200'>
<div className='flex-1'>
<p className='text-sm font-medium'>{key.description}</p>
<p className='text-xs text-gray-500 uppercase'>
Last used:{' '}
{key.lastUsedAt ? format(key.lastUsedAt, 'MMM d, yyyy HH:mm') : 'Never'}
</p>
</div>
<p className="text-sm text-gray-600 hidden md:block">
<code className="font-mono py-1 px-2 bg-gray-800 rounded text-white">
<p className='text-sm text-gray-600 hidden md:block'>
<code className='font-mono py-1 px-2 bg-gray-800 rounded text-white'>
{key.identifier}
</code>
</p>
<button
className="p-2 text-red-500 hover:text-red-700"
className='p-2 text-red-500 hover:text-red-700'
onClick={() => setDeleteIdentifier(key.identifier)}
>
<FontAwesomeIcon icon={faTrashAlt} size="lg" />
<FontAwesomeIcon icon={faTrashAlt} size='lg' />
</button>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions resources/scripts/components/dashboard/ApiKeyModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useContext } from 'react';
import ModalContext from '@/context/ModalContext';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import FlashMessageRender from '@/components/FlashMessageRender';
import Button from '@/components/elements/Button';
import CopyOnClick from '@/components/elements/CopyOnClick';
import FlashMessageRender from '@/components/FlashMessageRender';
Expand Down
28 changes: 14 additions & 14 deletions resources/scripts/components/dashboard/forms/CreateApiKeyForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { Field, Form, Formik, FormikHelpers } from 'formik';
import { useState } from 'react';
import { object, string } from 'yup';

import FlashMessageRender from '@/components/FlashMessageRender';
import ApiKeyModal from '@/components/dashboard/ApiKeyModal';
import Button from '@/components/elements/Button';
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
import Input from '@/components/elements/Input';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import FlashMessageRender from '@/components/FlashMessageRender';

import createApiKey from '@/api/account/createApiKey';
import { ApiKey } from '@/api/account/getApiKeys';
Expand Down Expand Up @@ -45,7 +45,7 @@ export default ({ onKeyCreated }: { onKeyCreated: (key: ApiKey) => void }) => {
return (
<>
{/* Flash Messages */}
<FlashMessageRender byKey="account" />
<FlashMessageRender byKey='account' />

{/* Modal for API Key */}
<ApiKeyModal visible={apiKey.length > 0} onModalDismissed={() => setApiKey('')} apiKey={apiKey} />
Expand All @@ -60,33 +60,33 @@ export default ({ onKeyCreated }: { onKeyCreated: (key: ApiKey) => void }) => {
})}
>
{({ isSubmitting }) => (
<Form className="space-y-6">
<Form className='space-y-6'>
{/* Show spinner overlay when submitting */}
<SpinnerOverlay visible={isSubmitting} />

{/* Description Field */}
<FormikFieldWrapper
label="Description"
name="description"
description="A description of this API key."
label='Description'
name='description'
description='A description of this API key.'
>
<Field name="description" as={Input} />
<Field name='description' as={Input} />
</FormikFieldWrapper>

{/* Allowed IPs Field */}
<FormikFieldWrapper
label="Allowed IPs"
name="allowedIps"
description="Leave blank to allow any IP address to use this API key, otherwise provide each IP address on a new line."
label='Allowed IPs'
name='allowedIps'
description='Leave blank to allow any IP address to use this API key, otherwise provide each IP address on a new line.'
>
<Field name="allowedIps" as={Input} />
<Field name='allowedIps' as={Input} />
</FormikFieldWrapper>

{/* Submit Button below form fields */}
<div className="flex justify-end mt-6">
<div className='flex justify-end mt-6'>
<Button
type="submit"
className="bg-red-600 text-white hover:bg-red-700 px-6 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500"
type='submit'
className='bg-red-600 text-white hover:bg-red-700 px-6 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500'
disabled={isSubmitting}
>
{isSubmitting ? 'Creating...' : 'Create API Key'}
Expand Down
30 changes: 15 additions & 15 deletions resources/scripts/components/dashboard/ssh/AccountSSHContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { format } from 'date-fns';
import { useEffect, useState } from 'react';

import FlashMessageRender from '@/components/FlashMessageRender';
import CreateSSHKeyForm from '@/components/dashboard/ssh/CreateSSHKeyForm';
import DeleteSSHKeyButton from '@/components/dashboard/ssh/DeleteSSHKeyButton';
import Code from '@/components/elements/Code';
import ContentBox from '@/components/elements/ContentBox';
import PageContentBlock from '@/components/elements/PageContentBlock';
Expand All @@ -13,8 +15,6 @@ import { Dialog } from '@/components/elements/dialog';
import { useSSHKeys } from '@/api/account/ssh-keys';

import { useFlashKey } from '@/plugins/useFlash';
import DeleteSSHKeyButton from '@/components/dashboard/ssh/DeleteSSHKeyButton';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

export default () => {
const [deleteIdentifier, setDeleteIdentifier] = useState('');
Expand All @@ -36,14 +36,14 @@ export default () => {
return (
<PageContentBlock title={'SSH Keys'}>
<FlashMessageRender byKey={'account'} />
<div className="md:flex flex-nowrap my-10 space-x-8">
<div className='md:flex flex-nowrap my-10 space-x-8'>
{/* Create SSH Key Section */}
<ContentBox title={'Add SSH Key'} className="flex-none w-full md:w-1/2">
<ContentBox title={'Add SSH Key'} className='flex-none w-full md:w-1/2'>
<CreateSSHKeyForm />
</ContentBox>

{/* SSH Keys List Section */}
<ContentBox title={'SSH Keys'} className="flex-1 overflow-hidden mt-8 md:mt-0">
<ContentBox title={'SSH Keys'} className='flex-1 overflow-hidden mt-8 md:mt-0'>
<SpinnerOverlay visible={!data && isValidating} />
<Dialog.Confirm
title={'Delete SSH Key'}
Expand All @@ -55,29 +55,29 @@ export default () => {
Deleting this key will revoke access for any system using it.
</Dialog.Confirm>
{!data || data.length === 0 ? (
<p className="text-center text-sm text-gray-500">
<p className='text-center text-sm text-gray-500'>
{!data ? 'Loading...' : 'No SSH keys exist for this account.'}
</p>
) : (
data.map((key) => (
<div key={key.fingerprint} className="flex flex-col mb-6 space-y-4">
<div className="flex items-center justify-between space-x-4 border border-gray-300 rounded-lg p-4 transition duration-200">
<div className="flex-1">
<p className="text-sm font-medium">{key.name}</p>
<p className="text-xs text-gray-500 uppercase">
<div key={key.fingerprint} className='flex flex-col mb-6 space-y-4'>
<div className='flex items-center justify-between space-x-4 border border-gray-300 rounded-lg p-4 transition duration-200'>
<div className='flex-1'>
<p className='text-sm font-medium'>{key.name}</p>
<p className='text-xs text-gray-500 uppercase'>
Added on: {format(key.createdAt, 'MMM d, yyyy HH:mm')}
</p>
</div>
<p className="text-sm text-gray-600 hidden md:block">
<code className="font-mono py-1 px-2 bg-gray-800 rounded text-white">
<p className='text-sm text-gray-600 hidden md:block'>
<code className='font-mono py-1 px-2 bg-gray-800 rounded text-white'>
SHA256: {key.fingerprint}
</code>
</p>
<button
className="p-2 text-red-500 hover:text-red-700"
className='p-2 text-red-500 hover:text-red-700'
onClick={() => setDeleteIdentifier(key.fingerprint)}
>
<FontAwesomeIcon icon={faTrashAlt} size="lg" />
<FontAwesomeIcon icon={faTrashAlt} size='lg' />
</button>
</div>
</div>
Expand Down
Loading

0 comments on commit 281fa9d

Please sign in to comment.