From 58df11c623a347f06b05ec0eb9de32e25ea308ab Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Mon, 8 Jun 2026 00:55:54 +0530 Subject: [PATCH] refactor: replace all displayField usages with displayFormat --- .dockerignore | 40 ++++++ .drone.yml | 140 +++++++++++++++++++++ Dockerfile | 33 +++++ react-openapi/components/EnhancedTable.tsx | 24 ++-- react-openapi/components/FilterBar.tsx | 2 +- 5 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 .dockerignore create mode 100644 .drone.yml create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fedd669 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,40 @@ +# Node modules +node_modules +**/node_modules + +# Logs +*.log +logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs +build +dist +out +.next +.cache +.parcel-cache + +# Environment files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# OS files +.DS_Store +Thumbs.db + +# IDE / Editor folders +.vscode +.idea +*.sublime-workspace +*.sublime-project + +# Temporary files +*.swp +*.bak +*.tmp diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..e7b64ab --- /dev/null +++ b/.drone.yml @@ -0,0 +1,140 @@ +--- +kind: pipeline +type: docker +name: default + +platform: + os: linux + arch: arm64 + +workspace: + path: /drone/src + +volumes: + - name: dockersock + host: + path: /var/run/docker.sock + +steps: + - name: fetch-tags + image: docker:24 + volumes: + - name: dockersock + path: /var/run/docker.sock + commands: + - apk add --no-cache git + - git fetch --tags + - | + # Get latest Git tag and trim newline + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null | tr -d '\n') + echo "Latest Git tag fetched: $LATEST_TAG" + + # Save to file for downstream steps + echo "$LATEST_TAG" > /drone/src/LATEST_TAG.txt + + # Read back for verification + IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n') + echo "Image tag read from file: $IMAGE_TAG" + + # Validate + if [ -z "$IMAGE_TAG" ]; then + echo "❌ No git tags found! Cannot continue." + exit 1 + fi + + - name: check-remote-image + image: docker:24 + volumes: + - name: dockersock + path: /var/run/docker.sock + commands: + - IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n') + + - echo "Checking if apps/khata:$IMAGE_TAG exists on remote Docker..." + - echo "Existing Docker tags for apps/khata:" + - docker images --format "{{.Repository}}:{{.Tag}}" | grep "^apps/khata" || echo "(none)" + - | + if docker image inspect apps/khata:$IMAGE_TAG > /dev/null 2>&1; then + echo "✅ Docker image apps/khata:$IMAGE_TAG already exists — skipping build" + exit 78 + else + echo "⚙️ Docker image apps/khata:$IMAGE_TAG not found — proceeding to build..." + fi + + - name: build-image + image: docker:24 + environment: + API_BASE_URL: + from_secret: API_BASE_URL + AUTH_BASE_URL: + from_secret: AUTH_BASE_URL + volumes: + - name: dockersock + path: /var/run/docker.sock + commands: + - IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n') + + - echo "🔨 Building Docker image apps/khata:$IMAGE_TAG ..." + - | + docker build --network=host \ + --build-arg VITE_API_BASE_URL="$API_BASE_URL" \ + --build-arg VITE_AUTH_BASE_URL="$AUTH_BASE_URL" \ + -t apps/khata:$IMAGE_TAG \ + -t apps/khata:latest \ + /drone/src + + - name: push-image + image: docker:24 + environment: + REGISTRY_HOST: + from_secret: REGISTRY_HOST + REGISTRY_USER: + from_secret: REGISTRY_USER + REGISTRY_PASS: + from_secret: REGISTRY_PASS + volumes: + - name: dockersock + path: /var/run/docker.sock + commands: + - IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n') + + - echo "🔑 Logging into registry $REGISTRY_HOST ..." + - echo "$REGISTRY_PASS" | docker login $REGISTRY_HOST -u "$REGISTRY_USER" --password-stdin + - echo "🏷️ Tagging images with registry prefix..." + - docker tag apps/khata:$IMAGE_TAG $REGISTRY_HOST/apps/khata:$IMAGE_TAG + - docker tag apps/khata:$IMAGE_TAG $REGISTRY_HOST/apps/khata:latest + - echo "📤 Pushing apps/khata:$IMAGE_TAG ..." + - docker push $REGISTRY_HOST/apps/khata:$IMAGE_TAG + - echo "📤 Pushing apps/khata:latest ..." + - docker push $REGISTRY_HOST/apps/khata:latest + + - name: stop-old + image: docker:24 + volumes: + - name: dockersock + path: /var/run/docker.sock + commands: + - echo "🛑 Stopping old container..." + - docker rm -f khata || true + + - name: run-container + image: docker:24 + volumes: + - name: dockersock + path: /var/run/docker.sock + commands: + - IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n') + + - echo "🚀 Starting container apps/khata:$IMAGE_TAG ..." + - | + docker run -d \ + --name khata \ + -p 3002:3000 \ + -e NODE_ENV=production \ + --restart always \ + apps/khata:$IMAGE_TAG + +# Trigger rules +trigger: + event: + - tag diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2943939 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +# Stage 1: Build +FROM node:20-alpine AS builder + +# Set working directory +WORKDIR /app + +# Copy package.json and package-lock.json (or yarn.lock) +COPY package*.json ./ + +# Install dependencies +RUN npm ci + +# Copy the rest of the app +COPY . . + +# Build the app +ARG VITE_API_BASE_URL +ARG VITE_AUTH_BASE_URL +RUN VITE_API_BASE_URL=$VITE_API_BASE_URL VITE_AUTH_BASE_URL=$VITE_AUTH_BASE_URL npm run build + +# Stage 2: Static file server (BusyBox) +FROM busybox:latest + +WORKDIR /app + +# Copy only build frontend files +COPY --from=builder /app/dist /app + +# Expose port +EXPOSE 3000 + +# Default command +CMD ["busybox", "httpd", "-f", "-p", "3000"] diff --git a/react-openapi/components/EnhancedTable.tsx b/react-openapi/components/EnhancedTable.tsx index ddc37ea..9999b45 100644 --- a/react-openapi/components/EnhancedTable.tsx +++ b/react-openapi/components/EnhancedTable.tsx @@ -278,19 +278,19 @@ function MobileCardRow({ row, config, onDelete, onNavigate, navigate, components ); } -function getFormattedDisplayValue(item: any, displayField?: string | string[], enumValue?: string) { +function getFormattedDisplayValue(item: any, displayFormat?: string | string[], enumValue?: string) { if (!item) return ""; if (enumValue) return resolveTemplate(enumValue, item); - if (!displayField) return item.name || item.title || item.label || item.id || JSON.stringify(item); + if (!displayFormat) return item.name || item.title || item.label || item.id || JSON.stringify(item); - if (Array.isArray(displayField)) { - return displayField - .map(key => item[key]) - .filter(val => val !== undefined && val !== null) - .join(' '); + if (Array.isArray(displayFormat)) { +return displayFormat + .map(key => item[key]) + .filter(val => val !== undefined && val !== null) + .join(' '); } - return item[displayField] || item.id || JSON.stringify(item); + return item[displayFormat] || item.id || JSON.stringify(item); } function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate, isMobile, components }: any) { @@ -307,7 +307,7 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate, // 1. Single Relation if (field.relation && value && !Array.isArray(value)) { const relationId = typeof value === 'object' ? (value.id || value._id || value.pk) : value; - const displayValue = getFormattedDisplayValue(value, field.displayField, field.enumOption?.value); + const displayValue = getFormattedDisplayValue(value, field.displayFormat, field.enumOption?.value); return ( getFormattedDisplayValue(item, field.displayField, enumValue)).join(', '); + const tooltipTitle = value.map((item) => getFormattedDisplayValue(item, field.displayFormat, enumValue)).join(', '); return ( @@ -335,7 +335,7 @@ function FieldRenderer({ params, field, fieldKey, config, onNavigate, navigate, {value.map((item, idx) => (