Improve deployment process and add login redirect logic

Deployment improvements:
- Add template env files (.envs.example/) for documentation
- Create init-production.sh for one-time server setup
- Create build-activepieces.sh for building/deploying AP image
- Update deploy.sh with --deploy-ap flag
- Make custom-pieces-metadata.sql idempotent
- Update DEPLOYMENT.md with comprehensive instructions

Frontend:
- Redirect logged-in business owners from root domain to tenant dashboard
- Redirect logged-in users from /login to /dashboard on their tenant
- Log out customers on wrong subdomain instead of redirecting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-20 23:13:56 -05:00
parent 2a33e4cf57
commit f8d8419622
38 changed files with 2471 additions and 396 deletions

View File

@@ -1,6 +1,6 @@
import { t } from 'i18next';
import { Plus, Globe } from 'lucide-react';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { useFormContext } from 'react-hook-form';
import { AutoFormFieldWrapper } from '@/app/builder/piece-properties/auto-form-field-wrapper';
@@ -80,6 +80,27 @@ function ConnectionSelect(params: ConnectionSelectProps) {
PropertyExecutionType.DYNAMIC;
const isPLatformAdmin = useIsPlatformAdmin();
// Auto-select connection with autoSelect metadata if no connection is selected
useEffect(() => {
if (isLoadingConnections || !connections?.data) return;
const currentAuth = form.getValues().settings.input.auth;
// Only auto-select if no connection is currently selected
if (currentAuth && removeBrackets(currentAuth)) return;
// Find a connection with autoSelect metadata
const autoSelectConnection = connections.data.find(
(connection) => (connection as any).metadata?.autoSelect === true
);
if (autoSelectConnection) {
form.setValue('settings.input.auth', addBrackets(autoSelectConnection.externalId), {
shouldValidate: true,
shouldDirty: true,
});
}
}, [connections?.data, isLoadingConnections, form]);
return (
<FormField
control={form.control}

View File

@@ -22,8 +22,8 @@ import { ScrollArea } from '@/components/ui/scroll-area';
import { LoadingSpinner } from '@/components/ui/spinner';
import { TemplateCard } from '@/features/templates/components/template-card';
import { TemplateDetailsView } from '@/features/templates/components/template-details-view';
import { useTemplates } from '@/features/templates/hooks/templates-hook';
import { Template, TemplateType } from '@activepieces/shared';
import { useAllTemplates } from '@/features/templates/hooks/templates-hook';
import { Template } from '@activepieces/shared';
const SelectFlowTemplateDialog = ({
children,
@@ -32,9 +32,7 @@ const SelectFlowTemplateDialog = ({
children: React.ReactNode;
folderId: string;
}) => {
const { filteredTemplates, isLoading, search, setSearch } = useTemplates({
type: TemplateType.CUSTOM,
});
const { filteredTemplates, isLoading, search, setSearch } = useAllTemplates();
const carousel = useRef<CarouselApi>();
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(
null,