diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 846055bdb..673115419 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -15,11 +15,35 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3 - - uses: actions/checkout@v3 + - name: Setup + uses: actions/setup-node@v3 + - name: Checkout + uses: actions/checkout@v3 + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Yarn cache + uses: actions/cache@v3 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: ${{ runner.os }}-yarn- + - name: Nextjs cache + uses: actions/cache@v2 + with: + # See here for caching with `yarn` https://github.com/actions/cache/blob/main/examples.md#node---yarn or you can leverage caching with actions/setup-node https://github.com/actions/setup-node + path: | + ~/.npm + ${{ github.workspace }}/.next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + # If source files changed but packages didn't, rebuild from a prior cache. + restore-keys: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- - run: yarn install --frozen-lockfile - run: yarn export - - uses: actions/cache@v2 + - name: Cache build output + uses: actions/cache@v2 id: restore-build with: path: ./out/ @@ -49,13 +73,8 @@ jobs: ghcr.io/ajnart/mhp # generate Docker tags based on the following events/attributes tags: | - type=schedule - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=sha + type=raw,value=latest,enable={{is_default_branch}} + type=pep440,pattern={{version}} - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx diff --git a/Dockerfile b/Dockerfile index ca782c441..d59093471 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,2 +1,2 @@ -FROM nginx:1.21.6 -COPY ./out /usr/share/nginx/html \ No newline at end of file +FROM nginx:alpine +COPY ./out /usr/share/nginx/html diff --git a/components/AppShelf/AddAppShelfItem.tsx b/components/AppShelf/AddAppShelfItem.tsx index 249c0d5e2..6858e1e46 100644 --- a/components/AppShelf/AddAppShelfItem.tsx +++ b/components/AppShelf/AddAppShelfItem.tsx @@ -10,9 +10,9 @@ import { AspectRatio, Text, Card, + LoadingOverlay, } from '@mantine/core'; -import { useForm } from '@mantine/hooks'; -import { UseForm } from '@mantine/hooks/lib/use-form/use-form'; +import { useForm } from '@mantine/form'; import { motion } from 'framer-motion'; import { useState } from 'react'; import { Apps } from 'tabler-icons-react'; @@ -94,10 +94,12 @@ function MatchIcon( return false; } - + export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & any) { const { setOpened } = props; const { addService, config, setConfig } = useConfig(); + const [isLoading, setLoading] = useState(false); + const form = useForm({ initialValues: { type: props.type ?? 'Other', @@ -106,6 +108,23 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & url: props.url ?? '', apiKey: props.apiKey ?? (undefined as unknown as string), }, + validate: { + apiKey: (value: string) => null, + // Validate icon with a regex + icon: (value: string) => { + if (!value.match(/^https?:\/\/.+\.(png|jpg|jpeg|gif)$/)) { + return 'Please enter a valid icon URL'; + } + return null; + }, + // Validate url with a regex http/https + url: (value: string) => { + if (!value.match(/^https?:\/\/.+\/$/)) { + return 'Please enter a valid URL (that ends with a /)'; + } + return null; + }, + }, }); return ( @@ -148,44 +167,40 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & form.setFieldValue('icon', match); } }} - error={form.errors.name && 'Invalid name'} + error={form.errors.name && 'Invalid icon url'} /> { - form.setFieldValue('icon', event.currentTarget.value); - }} - error={form.errors.icon && 'Icon url is invalid'} + {...form.getInputProps('icon')} /> form.setFieldValue('url', event.currentTarget.value)} - error={form.errors.url && 'Service url is invalid'} + {...form.getInputProps('url')} />