diff --git a/.cspell.json b/.cspell.json index 924429a66..024df3872 100644 --- a/.cspell.json +++ b/.cspell.json @@ -4,332 +4,323 @@ "caseSensitive": false, "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", "words": [ - "appdev", - "gauzystage", + "accepte", + "Accordian", "adipiscing", - "amet", "aliqua", - "signin", + "amet", + "Andross", + "animatable", + "apidev", + "apisauce", + "apistage", + "appdev", + "appkey", + "applesimutils", "APPSTORE", + "arrowleft", + "asel", + "Authentificate", "barcodes", + "billrate", "binutils", + "Boilerplates", + "bootsplash", + "borde", + "Bowser", + "Btns", + "Bugsnag", "buildjet", "cacheable", "camelcase", + "capitaliz", + "Chami", + "Chane", + "Changemail", + "Charaters", "Chatwoot", + "cheched", + "checkcircle", + "checkcircleo", "chetwode", + "choos", + "ciphertext", + "classpath", "cloc", + "clockcircleo", "cloudinary", "clsx", "clsxm", - "opentelemetry", - "otlp", + "Cmbx", + "cmdk", + "Codacy", + "codecov", + "Codementor", + "Combox", + "combx", "commitlint", - "DONT", - "greenkeeper", - "classpath", - "tsbuildinfo", - "sentryclirc", + "comparision", "compodoc", "consectetur", + "contaniner", + "creatoe", + "Darkmode", + "datas", + "Defaul", + "Descrption", + "deserunt", + "dimesions", + "discrepenancy", "dolor", "dolore", + "domhandler", + "domutils", + "DONT", + "dotenv", + "Dropown", + "dropwdown", "dummyimage", + "dvalue", + "Efate", "eiusmod", "elit", + "ellipsize", + "embla", + "Enderbury", + "endregion", + "Entypo", "envalid", + "errr", "everco", "everteamsdesktop", + "excalidraw", + "exclamationcircleo", "exposdk", + "extramenu", + "Fakaofo", + "falsey", + "fbjs", + "Ffeeds", + "Filder", + "filtmembers", + "firstname", + "flaticon", + "fomated", + "Formated", + "FULLNAME", + "Funtion", + "Galery", + "gauzystage", "gcloud", + "Gitter", + "gradlew", "graphicsmagick", + "greenkeeper", + "greppable", + "grotesk", "gtag", + "Hanlder", "headlessui", + "Heinze", "heroicons", - "overlapper", + "hidde", + "Holmgren", + "horcrux", + "HUBSTAFF", "Huhn", + "huntr", + "hwba", + "hyperscript", + "ianatz", "icnsutils", + "Icontent", + "imagebutton", + "imlement", + "immediatly", + "imodal", + "implem", + "INAPP", "incididunt", + "INFOTMATION", + "inital", + "Instanciate", + "insted", + "Intervall", + "invdate", + "Invitatio", + "invitationid", + "Invitions", + "Ionicons", + "iphonesimulator", + "ipsum", "isdragging", "isdraggingfrom", "isdropdisabled", - "ipsum", + "Isssue", + "ISSUETYPE", + "Isvalid", + "itask", + "iuser", + "Jamon", + "jitsi", "JITSU", + "jsbundle", "kanban", + "Kanbanboard", "kanbandata", - "Lorem", + "Kiritimati", + "Kolkata", + "Kosrae", + "labore", + "Lask", + "lastest", + "lastlog", + "lgcard", "libappindicator", + "Lngs", + "Loadtasks", + "localstorage", + "locatio", + "loglevel", + "longpress", + "Lorem", "lucide", + "mappagination", "mathieudutour", + "Mazen", + "Metral", + "miliseconds", + "millisencods", + "mobx", + "Moresby", "ncipollo", + "Neue", "nextjs", + "nimg", + "nocheck", + "noreferrer", + "Opena", + "opentelemetry", + "Ordereds", + "Organizatio", + "OSTYPE", + "otlp", + "outclick", + "overlapper", + "Pago", + "pako", + "paren", + "Parens", "passcode", + "payperiod", + "Permisson", + "Personnal", + "phraseapp", + "pkill", + "Plaholder", "plasmo", + "plasmohq", + "popperjs", + "Pourtcent", "precommit", + "Pressable", + "Pressible", + "progess", + "Proguard", + "Propf", + "publicactive", + "reactotron", + "Reactotron's", "RECAPTCHA", + "recieve", + "Reconds", + "Repobeats", + "RESERVERD", + "Rickert", + "runned", + "Screenshoot", + "screenshoots", + "SCREENSHOOTS", + "screenstatus", + "sentryclirc", + "setrole", + "Settingfilter", "setuptools", "setwin", + "shadcn", + "shandow", + "signin", + "Signle", + "signoff", + "simplecast", + "sitekey", + "skey", + "smalltext", "snyk", + "stackoverflow", + "statsus", + "statut", + "STMP", + "strock", "stylelint", + "stylesheet", + "subsquently", "svgs", - "Tailess", + "Swith", + "Syle", + "Synk", "tailess", + "Tailess", "tailwindcss", - "testid", - "Timesheet", "tanstack", + "taskid", "taskstatus", + "teamtask", "tempor", - "vcpu", - "Vercel", - "HUBSTAFF", - "UPWORK", - "runned", + "testid", + "Timesheet", + "Timesheets", "Timeslot", - "Isssue", - "datas", - "Changemail", - "Lask", - "publicactive", - "Formated", - "Btns", - "RESERVERD", - "shandow", - "UIUX", - "xlight", - "domutils", - "domhandler", - "hyperscript", - "nocheck", - "locatio", - "labore", - "falsey", - "unhang", - "popperjs", - "Isssue", - "inital", - "FULLNAME", - "extramenu", - "iuser", - "Pourtcent", - "Reconds", - "Pourtcent", - "combx", - "fomated", - "Hanlder", - "cmdk", - "sitekey", - "Loadtasks", - "Accordian", - "lgcard", - "dvalue", - "Codacy", - "codecov", - "huntr", - "Gitter", - "shadcn", - "Repobeats", - "Codementor", - "xlcard", - "wght", - "worksace", - "appkey", - "jitsi", - "accepte", - "Parens", - "pako", - "embla", - "excalidraw", - "Lngs", - "Transpiles", - "wasabisys", - "apistage", - "flaticon", - "VERSONS", - "vertificalline", + "tinvitations", + "tnode", + "Togger", "Tongatapu", - "Moresby", - "Pago", - "Kosrae", - "Kiritimati", - "Fakaofo", - "Enderbury", - "Efate", - "Propf", - "mappagination", - "INAPP", - "INFOTMATION", - "nimg", - "strock", - "ISSUETYPE", - "borde", - "imlement", - "Invitatio", - "Synk", - "nimg", - "capitaliz", - "nimg", - "Settingfilter", - "recieve", - "Opena", + "tota", "TRANSFERT", - "choos", - "Darkmode", - "recieve", - "Vefified", + "Transpiles", + "tsbuildinfo", + "typeof", + "uicolors", + "uidotdev", + "UIUX", + "unasigned", + "unchild", + "unhang", + "unimodules", + "unoffic", + "UPWORK", + "usehooks", "Uturn", - "insted", - "Cmbx", - "hidde", - "invitationid", - "cheched", - "Dropown", - "imodal", - "Signle", - "Filder", - "outclick", - "Filder", - "skey", - "outclick", - "Xlarge", - "Permisson", - "noreferrer", - "errr", - "Instanciate", "Varibales", - "ciphertext", - "discrepenancy", - "unoffic", - "implem", - "asel", - "Togger", - "Organizatio", - "Combox", - "unchild", - "signoff", - "Settingfilter", - "X", - "stackoverflow", - "payperiod", - "billrate", - "tnode", - "localstorage", - "millisencods", - "taskid", - "creatoe", - "setrole", - "lastest", - "immediatly", + "vcpu", + "Vefified", + "Vercel", "Verifiy", - "invdate", - "ianatz", - "uicolors", - "greppable", - "Andross", - "Bowser", - "Boilerplates", + "VERSONS", + "vertificalline", + "wasabisys", + "wght", + "withteam", + "worksace", + "Worspace", + "X", + "xcodebuild", "xcodeproj", - "gradlew", - "paren", - "iphonesimulator", "xcworkspace", - "dropwdown", - "itask", - "xcodebuild", - "reactotron", - "fbjs", - "stylesheet", - "bootsplash", - "animatable", - "apisauce", - "grotesk", - "jsbundle", - "unimodules", - "mobx", - "typeof", - "loglevel", - "applesimutils", - "phraseapp", - "OSTYPE", - "pkill", - "yellowbox", - "miliseconds", - "Bugsnag", - "Neue", - "Defaul", - "Reactotron's", - "Worspace", - "Funtion", - "tinvitations", - "Authentificate", - "screenstatus", - "withteam", - "Invitions", - "lastlog", - "STMP", - "statut", - "statsus", - "simplecast", - "Ffeeds", - "smalltext", - "Pressible", - "Pressable", - "deserunt", - "longpress", - "endregion", - "checkcircleo", - "Entypo", - "Charaters", - "Ionicons", - "ellipsize", - "unasigned", - "progess", - "Icontent", - "arrowleft", - "Descrption", - "Swith", - "Chane", - "Plaholder", - "firstname", - "Isvalid", - "Chane", - "checkcircle", - "exclamationcircleo", - "contaniner", - "Galery", - "clockcircleo", - "filtmembers", - "comparision", - "Jamon", - "Chami", - "Mazen", - "Heinze", - "Kanbanboard", - "Kolkata", - "Holmgren", - "Jamon", - "Rickert", - "Metral", - "subsquently", - "Syle", - "teamtask", - "imagebutton", - "hwba", - "plasmohq", - "Proguard", - "horcrux", - "dimesions", - "Ordereds", - "uidotdev", - "usehooks", - "Personnal", - "SCREENSHOOTS", - "Screenshoot", - "screenshoots", - "tota", - "Intervall", - "Timesheets", - "dotenv" + "Xlarge", + "xlcard", + "xlight", + "yellowbox" ], "useGitignore": true, "ignorePaths": [ diff --git a/.deploy/k8s/k8s-manifest-api.dev.yaml b/.deploy/k8s/k8s-manifest-api.dev.yaml new file mode 100644 index 000000000..4c9f01c8a --- /dev/null +++ b/.deploy/k8s/k8s-manifest-api.dev.yaml @@ -0,0 +1,82 @@ +--- +kind: Service +apiVersion: v1 +metadata: + name: ever-teams-dev-api-lb + annotations: + service.beta.kubernetes.io/do-loadbalancer-name: 'apidev.ever.team' + service.beta.kubernetes.io/do-loadbalancer-protocol: 'http2' + service.beta.kubernetes.io/do-loadbalancer-http2-ports: '443' + # Replace with your Certificate Id. You can get a list of Ids with 'doctl compute certificate list' + service.beta.kubernetes.io/do-loadbalancer-certificate-id: '0c4085c5-9692-4320-86f3-34f52b775a88' + service.beta.kubernetes.io/do-loadbalancer-size-slug: 'lb-small' + service.beta.kubernetes.io/do-loadbalancer-hostname: 'apidev.ever.team' +spec: + type: LoadBalancer + selector: + app: ever-teams-dev-api + ports: + - name: http + protocol: TCP + port: 443 + targetPort: 3000 +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: ever-teams-dev-api +spec: + replicas: 1 + selector: + matchLabels: + app: ever-teams-dev-api + template: + metadata: + labels: + app: ever-teams-dev-api + spec: + containers: + - name: ever-teams-dev-api + image: registry.digitalocean.com/ever/gauzy-api-demo:latest + env: + - name: API_HOST + value: 0.0.0.0 + - name: DEMO + value: 'true' + - name: CLOUD_PROVIDER + value: '$CLOUD_PROVIDER' + - name: NODE_ENV + value: 'development' + - name: ADMIN_PASSWORD_RESET + value: 'true' + - name: LOG_LEVEL + value: 'info' + - name: SENTRY_DSN + value: '$SENTRY_DSN' + - name: SENTRY_HTTP_TRACING_ENABLED + value: '$SENTRY_HTTP_TRACING_ENABLED' + - name: SENTRY_PROFILING_ENABLED + value: '$SENTRY_PROFILING_ENABLED' + - name: SENTRY_POSTGRES_TRACKING_ENABLED + value: '$SENTRY_POSTGRES_TRACKING_ENABLED' + - name: API_BASE_URL + value: 'https://apidev.ever.team' + - name: CLIENT_BASE_URL + value: 'https://demo.ever.team' + - name: EXPRESS_SESSION_SECRET + value: 'gauzy' + - name: JWT_SECRET + value: 'secretKey' + - name: JWT_REFRESH_TOKEN_SECRET + value: 'refreshSecretKey' + - name: JWT_REFRESH_TOKEN_EXPIRATION_TIME + value: '86400' + - name: OTEL_ENABLED + value: '$OTEL_ENABLED' + - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT + value: '$OTEL_EXPORTER_OTLP_TRACES_ENDPOINT' + - name: OTEL_EXPORTER_OTLP_HEADERS + value: '$OTEL_EXPORTER_OTLP_HEADERS' + ports: + - containerPort: 3000 + protocol: TCP diff --git a/.deploy/k8s/k8s-manifest-api.prod.yaml b/.deploy/k8s/k8s-manifest-api.prod.yaml new file mode 100644 index 000000000..3a82c54ae --- /dev/null +++ b/.deploy/k8s/k8s-manifest-api.prod.yaml @@ -0,0 +1,234 @@ +--- +kind: Service +apiVersion: v1 +metadata: + name: ever-teams-prod-api-lb + annotations: + service.beta.kubernetes.io/do-loadbalancer-name: 'api.ever.team' + service.beta.kubernetes.io/do-loadbalancer-protocol: 'http2' + service.beta.kubernetes.io/do-loadbalancer-http2-ports: '443' + # Replace with your Certificate Id. You can get a list of Ids with 'doctl compute certificate list' + service.beta.kubernetes.io/do-loadbalancer-certificate-id: '0c4085c5-9692-4320-86f3-34f52b775a88' + service.beta.kubernetes.io/do-loadbalancer-size-slug: 'lb-small' + service.beta.kubernetes.io/do-loadbalancer-hostname: 'api.ever.team' +spec: + type: LoadBalancer + selector: + app: ever-teams-prod-api + ports: + - name: http + protocol: TCP + port: 443 + targetPort: 3000 +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: ever-teams-prod-api +spec: + replicas: 3 + selector: + matchLabels: + app: ever-teams-prod-api + template: + metadata: + labels: + app: ever-teams-prod-api + spec: + containers: + - name: ever-teams-prod-api + image: registry.digitalocean.com/ever/gauzy-api:latest + resources: + requests: + memory: '1536Mi' + cpu: '1000m' + limits: + memory: '2048Mi' + env: + - name: API_HOST + value: 0.0.0.0 + - name: DEMO + value: 'false' + - name: NODE_ENV + value: 'production' + - name: ADMIN_PASSWORD_RESET + value: 'true' + - name: LOG_LEVEL + value: 'info' + - name: CLOUD_PROVIDER + value: '$CLOUD_PROVIDER' + - name: SENTRY_DSN + value: '$SENTRY_DSN' + - name: SENTRY_HTTP_TRACING_ENABLED + value: '$SENTRY_HTTP_TRACING_ENABLED' + - name: SENTRY_PROFILING_ENABLED + value: '$SENTRY_PROFILING_ENABLED' + - name: SENTRY_POSTGRES_TRACKING_ENABLED + value: '$SENTRY_POSTGRES_TRACKING_ENABLED' + - name: API_BASE_URL + value: 'https://api.ever.team' + - name: CLIENT_BASE_URL + value: 'https://app.ever.team' + - name: DB_URI + value: '$DB_URI' + - name: DB_HOST + value: '$DB_HOST' + - name: DB_SSL_MODE + value: '$DB_SSL_MODE' + - name: DB_CA_CERT + value: '$DB_CA_CERT' + - name: DB_USER + value: '$DB_USER' + - name: DB_PASS + value: '$DB_PASS' + - name: DB_TYPE + value: '$DB_TYPE' + - name: DB_NAME + value: '$DB_NAME' + - name: DB_PORT + value: '$DB_PORT' + - name: REDIS_ENABLED + value: '$REDIS_ENABLED' + - name: REDIS_URL + value: '$REDIS_URL' + - name: AWS_ACCESS_KEY_ID + value: '$AWS_ACCESS_KEY_ID' + - name: AWS_SECRET_ACCESS_KEY + value: '$AWS_SECRET_ACCESS_KEY' + - name: AWS_REGION + value: '$AWS_REGION' + - name: AWS_S3_BUCKET + value: '$AWS_S3_BUCKET' + - name: WASABI_ACCESS_KEY_ID + value: '$WASABI_ACCESS_KEY_ID' + - name: WASABI_SECRET_ACCESS_KEY + value: '$WASABI_SECRET_ACCESS_KEY' + - name: WASABI_REGION + value: '$WASABI_REGION' + - name: WASABI_SERVICE_URL + value: '$WASABI_SERVICE_URL' + - name: WASABI_S3_BUCKET + value: '$WASABI_S3_BUCKET' + - name: EXPRESS_SESSION_SECRET + value: '$EXPRESS_SESSION_SECRET' + - name: JWT_SECRET + value: '$JWT_SECRET' + - name: JWT_REFRESH_TOKEN_SECRET + value: '$JWT_REFRESH_TOKEN_SECRET' + - name: JWT_REFRESH_TOKEN_EXPIRATION_TIME + value: '$JWT_REFRESH_TOKEN_EXPIRATION_TIME' + - name: CLOUDINARY_API_KEY + value: '$CLOUDINARY_API_KEY' + - name: CLOUDINARY_API_SECRET + value: '$CLOUDINARY_API_SECRET' + - name: CLOUDINARY_CLOUD_NAME + value: '$CLOUDINARY_CLOUD_NAME' + - name: DEFAULT_CURRENCY + value: 'USD' + - name: MAIL_FROM_ADDRESS + value: '$MAIL_FROM_ADDRESS' + - name: MAIL_HOST + value: '$MAIL_HOST' + - name: MAIL_PORT + value: '$MAIL_PORT' + - name: MAIL_USERNAME + value: '$MAIL_USERNAME' + - name: MAIL_PASSWORD + value: '$MAIL_PASSWORD' + - name: ALLOW_SUPER_ADMIN_ROLE + value: '$ALLOW_SUPER_ADMIN_ROLE' + - name: GOOGLE_CLIENT_ID + value: '$GOOGLE_CLIENT_ID' + - name: GOOGLE_CLIENT_SECRET + value: '$GOOGLE_CLIENT_SECRET' + - name: GOOGLE_CALLBACK_URL + value: '$GOOGLE_CALLBACK_URL' + - name: FACEBOOK_CLIENT_ID + value: '$FACEBOOK_CLIENT_ID' + - name: FACEBOOK_CLIENT_SECRET + value: '$FACEBOOK_CLIENT_SECRET' + - name: FACEBOOK_GRAPH_VERSION + value: '$FACEBOOK_GRAPH_VERSION' + - name: FACEBOOK_CALLBACK_URL + value: '$FACEBOOK_CALLBACK_URL' + - name: INTEGRATED_USER_DEFAULT_PASS + value: '$INTEGRATED_USER_DEFAULT_PASS' + - name: UPWORK_REDIRECT_URL + value: '$UPWORK_REDIRECT_URL' + - name: FILE_PROVIDER + value: '$FILE_PROVIDER' + - name: GAUZY_AI_GRAPHQL_ENDPOINT + value: '$GAUZY_AI_GRAPHQL_ENDPOINT' + - name: GAUZY_AI_REST_ENDPOINT + value: '$GAUZY_AI_REST_ENDPOINT' + - name: UNLEASH_APP_NAME + value: '$UNLEASH_APP_NAME' + - name: UNLEASH_API_URL + value: '$UNLEASH_API_URL' + - name: UNLEASH_INSTANCE_ID + value: '$UNLEASH_INSTANCE_ID' + - name: UNLEASH_REFRESH_INTERVAL + value: '$UNLEASH_REFRESH_INTERVAL' + - name: UNLEASH_METRICS_INTERVAL + value: '$UNLEASH_METRICS_INTERVAL' + - name: UNLEASH_API_KEY + value: '$UNLEASH_API_KEY' + - name: PM2_PUBLIC_KEY + value: '$PM2_PUBLIC_KEY' + - name: PM2_SECRET_KEY + value: '$PM2_SECRET_KEY' + - name: PM2_MACHINE_NAME + value: '$PM2_MACHINE_NAME' + - name: JITSU_SERVER_URL + value: '$JITSU_SERVER_URL' + - name: JITSU_SERVER_WRITE_KEY + value: '$JITSU_SERVER_WRITE_KEY' + - name: OTEL_ENABLED + value: '$OTEL_ENABLED' + - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT + value: '$OTEL_EXPORTER_OTLP_TRACES_ENDPOINT' + - name: OTEL_EXPORTER_OTLP_HEADERS + value: '$OTEL_EXPORTER_OTLP_HEADERS' + - name: GAUZY_GITHUB_CLIENT_ID + value: '$GAUZY_GITHUB_CLIENT_ID' + - name: GAUZY_GITHUB_CLIENT_SECRET + value: '$GAUZY_GITHUB_CLIENT_SECRET' + - name: GAUZY_GITHUB_WEBHOOK_URL + value: '$GAUZY_GITHUB_WEBHOOK_URL' + - name: GAUZY_GITHUB_WEBHOOK_SECRET + value: '$GAUZY_GITHUB_WEBHOOK_SECRET' + - name: GAUZY_GITHUB_APP_PRIVATE_KEY + value: '$GAUZY_GITHUB_APP_PRIVATE_KEY' + - name: GAUZY_GITHUB_APP_ID + value: '$GAUZY_GITHUB_APP_ID' + - name: GAUZY_GITHUB_APP_NAME + value: '$GAUZY_GITHUB_APP_NAME' + - name: GAUZY_GITHUB_POST_INSTALL_URL + value: '$GAUZY_GITHUB_POST_INSTALL_URL' + - name: GAUZY_GITHUB_OAUTH_CLIENT_ID + value: '$GAUZY_GITHUB_OAUTH_CLIENT_ID' + - name: GAUZY_GITHUB_OAUTH_CLIENT_SECRET + value: '$GAUZY_GITHUB_OAUTH_CLIENT_SECRET' + - name: GAUZY_GITHUB_OAUTH_CALLBACK_URL + value: '$GAUZY_GITHUB_OAUTH_CALLBACK_URL' + - name: MAGIC_CODE_EXPIRATION_TIME + value: '$MAGIC_CODE_EXPIRATION_TIME' + - name: APP_NAME + value: '$APP_NAME' + - name: APP_LOGO + value: '$APP_LOGO' + - name: APP_SIGNATURE + value: '$APP_SIGNATURE' + - name: APP_LINK + value: '$APP_LINK' + - name: APP_EMAIL_CONFIRMATION_URL + value: '$APP_EMAIL_CONFIRMATION_URL' + - name: APP_MAGIC_SIGN_URL + value: '$APP_MAGIC_SIGN_URL' + - name: COMPANY_LINK + value: '$COMPANY_LINK' + - name: COMPANY_NAME + value: '$COMPANY_NAME' + ports: + - containerPort: 3000 + protocol: TCP diff --git a/.deploy/k8s/k8s-manifest.dev.yaml b/.deploy/k8s/k8s-manifest.dev.yaml index f7416b2ec..b1430904b 100644 --- a/.deploy/k8s/k8s-manifest.dev.yaml +++ b/.deploy/k8s/k8s-manifest.dev.yaml @@ -22,8 +22,8 @@ spec: targetPort: 3000 --- -apiVersion: apps/v1 kind: Deployment +apiVersion: apps/v1 metadata: name: ever-teams-dev-webapp spec: diff --git a/.deploy/k8s/k8s-manifest.prod.yaml b/.deploy/k8s/k8s-manifest.prod.yaml index ef23a5e55..555f85805 100644 --- a/.deploy/k8s/k8s-manifest.prod.yaml +++ b/.deploy/k8s/k8s-manifest.prod.yaml @@ -22,8 +22,8 @@ spec: targetPort: 3000 --- -apiVersion: apps/v1 kind: Deployment +apiVersion: apps/v1 metadata: name: ever-teams-prod-webapp spec: diff --git a/.github/workflows/deploy-api-do-dev.yml b/.github/workflows/deploy-api-do-dev.yml new file mode 100644 index 000000000..10c160403 --- /dev/null +++ b/.github/workflows/deploy-api-do-dev.yml @@ -0,0 +1,53 @@ +name: Deploy API to DigitalOcean Dev + +on: + push: + branches: [develop] + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + deploy-api-dev: + runs-on: buildjet-4vcpu-ubuntu-2204 + + environment: dev + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install doctl + uses: digitalocean/action-doctl@v2 + with: + token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} + + - name: Log in to DigitalOcean Container Registry with short-lived credentials + run: doctl registry login --expiry-seconds 600 + + - name: Save DigitalOcean kubeconfig with short-lived credentials + run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 k8s-gauzy + + - name: Apply k8s manifests changes in DigitalOcean k8s cluster (if any) + run: | + envsubst < $GITHUB_WORKSPACE/.deploy/k8s/k8s-manifest-api.dev.yaml | kubectl --context do-sfo2-k8s-gauzy apply -f - + env: + # below we are using GitHub secrets for both frontend and backend + CLOUD_PROVIDER: 'DO' + DB_NAME: '${{ secrets.DB_NAME }}' + SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' + SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' + SENTRY_PROFILE_SAMPLE_RATE: '${{ secrets.SENTRY_PROFILE_SAMPLE_RATE }}' + SENTRY_HTTP_TRACING_ENABLED: '${{ secrets.SENTRY_HTTP_TRACING_ENABLED }}' + SENTRY_POSTGRES_TRACKING_ENABLED: '${{ secrets.SENTRY_POSTGRES_TRACKING_ENABLED }}' + SENTRY_PROFILING_ENABLED: '${{ secrets.SENTRY_PROFILING_ENABLED }}' + OTEL_ENABLED: '${{ secrets.OTEL_ENABLED }}' + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '${{ secrets.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT }}' + OTEL_EXPORTER_OTLP_HEADERS: '${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}' + + # we need this step because for now we just use :latest tag + # note: for production we will use different strategy later + - name: Restart Pods to pick up :latest tag version + run: | + kubectl --context do-sfo2-k8s-gauzy rollout restart deployment/ever-teams-dev-api diff --git a/.github/workflows/deploy-api-do-prod.yml b/.github/workflows/deploy-api-do-prod.yml new file mode 100644 index 000000000..b6269dc69 --- /dev/null +++ b/.github/workflows/deploy-api-do-prod.yml @@ -0,0 +1,131 @@ +name: Deploy API to DigitalOcean Prod + +on: + push: + branches: [main] + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + deploy-api-prod: + runs-on: buildjet-4vcpu-ubuntu-2204 + + environment: prod + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install doctl + uses: digitalocean/action-doctl@v2 + with: + token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} + + - name: Log in to DigitalOcean Container Registry with short-lived credentials + run: doctl registry login --expiry-seconds 600 + + - name: Save DigitalOcean kubeconfig with short-lived credentials + run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 k8s-gauzy + + - name: Apply k8s manifests changes in DigitalOcean k8s cluster (if any) + run: | + envsubst < $GITHUB_WORKSPACE/.deploy/k8s/k8s-manifest-api.prod.yaml | kubectl --context do-sfo2-k8s-gauzy apply -f - + env: + # below we are using GitHub secrets for both frontend and backend + DB_TYPE: '${{ secrets.DB_TYPE }}' + DB_URI: '${{ secrets.DB_URI }}' + DB_HOST: '${{ secrets.DB_HOST }}' + DB_USER: '${{ secrets.DB_USER }}' + DB_PASS: '${{ secrets.DB_PASS }}' + DB_NAME: '${{ secrets.DB_NAME }}' + DB_PORT: '${{ secrets.DB_PORT }}' + DB_CA_CERT: '${{ secrets.DB_CA_CERT }}' + DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}' + REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}' + REDIS_URL: '${{ secrets.REDIS_URL }}' + CLOUD_PROVIDER: 'DO' + SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' + SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' + SENTRY_PROFILE_SAMPLE_RATE: '${{ secrets.SENTRY_PROFILE_SAMPLE_RATE }}' + SENTRY_HTTP_TRACING_ENABLED: '${{ secrets.SENTRY_HTTP_TRACING_ENABLED }}' + SENTRY_POSTGRES_TRACKING_ENABLED: '${{ secrets.SENTRY_POSTGRES_TRACKING_ENABLED }}' + SENTRY_PROFILING_ENABLED: '${{ secrets.SENTRY_PROFILING_ENABLED }}' + AWS_ACCESS_KEY_ID: '${{ secrets.AWS_ACCESS_KEY_ID }}' + AWS_SECRET_ACCESS_KEY: '${{ secrets.AWS_SECRET_ACCESS_KEY }}' + AWS_REGION: '${{ secrets.AWS_REGION }}' + AWS_S3_BUCKET: '${{ secrets.AWS_S3_BUCKET }}' + WASABI_ACCESS_KEY_ID: '${{ secrets.WASABI_ACCESS_KEY_ID }}' + WASABI_SECRET_ACCESS_KEY: '${{ secrets.WASABI_SECRET_ACCESS_KEY }}' + WASABI_REGION: '${{ secrets.WASABI_REGION }}' + WASABI_SERVICE_URL: '${{ secrets.WASABI_SERVICE_URL }}' + WASABI_S3_BUCKET: '${{ secrets.WASABI_S3_BUCKET }}' + EXPRESS_SESSION_SECRET: '${{ secrets.EXPRESS_SESSION_SECRET }}' + JWT_SECRET: '${{ secrets.JWT_SECRET }}' + JWT_REFRESH_TOKEN_SECRET: '${{ secrets.JWT_REFRESH_TOKEN_SECRET }}' + JWT_REFRESH_TOKEN_EXPIRATION_TIME: '${{ secrets.JWT_REFRESH_TOKEN_EXPIRATION_TIME }}' + CLOUDINARY_API_KEY: '${{ secrets.CLOUDINARY_API_KEY }}' + CLOUDINARY_API_SECRET: '${{ secrets.CLOUDINARY_API_SECRET }}' + CLOUDINARY_CLOUD_NAME: '${{ secrets.CLOUDINARY_CLOUD_NAME }}' + MAIL_FROM_ADDRESS: '${{ secrets.MAIL_FROM_ADDRESS }}' + MAIL_HOST: '${{ secrets.MAIL_HOST }}' + MAIL_PORT: '${{ secrets.MAIL_PORT }}' + MAIL_USERNAME: '${{ secrets.MAIL_USERNAME }}' + MAIL_PASSWORD: '${{ secrets.MAIL_PASSWORD }}' + ALLOW_SUPER_ADMIN_ROLE: '${{ secrets.ALLOW_SUPER_ADMIN_ROLE }}' + GOOGLE_CLIENT_ID: '${{ secrets.GOOGLE_CLIENT_ID }}' + GOOGLE_CLIENT_SECRET: '${{ secrets.GOOGLE_CLIENT_SECRET }}' + GOOGLE_CALLBACK_URL: '${{ secrets.GOOGLE_CALLBACK_URL }}' + FACEBOOK_CLIENT_ID: '${{ secrets.FACEBOOK_CLIENT_ID }}' + FACEBOOK_CLIENT_SECRET: '${{ secrets.FACEBOOK_CLIENT_SECRET }}' + FACEBOOK_GRAPH_VERSION: '${{ secrets.FACEBOOK_GRAPH_VERSION }}' + FACEBOOK_CALLBACK_URL: '${{ secrets.FACEBOOK_CALLBACK_URL }}' + INTEGRATED_USER_DEFAULT_PASS: '${{ secrets.INTEGRATED_USER_DEFAULT_PASS }}' + UPWORK_REDIRECT_URL: '${{ secrets.UPWORK_REDIRECT_URL }}' + FILE_PROVIDER: '${{ secrets.FILE_PROVIDER }}' + GAUZY_AI_GRAPHQL_ENDPOINT: '${{ secrets.GAUZY_AI_GRAPHQL_ENDPOINT }}' + GAUZY_AI_REST_ENDPOINT: '${{ secrets.GAUZY_AI_REST_ENDPOINT }}' + UNLEASH_APP_NAME: '${{ secrets.UNLEASH_APP_NAME }}' + UNLEASH_API_URL: '${{ secrets.UNLEASH_API_URL }}' + UNLEASH_INSTANCE_ID: '${{ secrets.UNLEASH_INSTANCE_ID }}' + UNLEASH_REFRESH_INTERVAL: '${{ secrets.UNLEASH_REFRESH_INTERVAL }}' + UNLEASH_METRICS_INTERVAL: '${{ secrets.UNLEASH_METRICS_INTERVAL }}' + UNLEASH_API_KEY: '${{ secrets.UNLEASH_API_KEY }}' + PM2_MACHINE_NAME: '${{ secrets.PM2_MACHINE_NAME }}' + PM2_SECRET_KEY: '${{ secrets.PM2_SECRET_KEY }}' + PM2_PUBLIC_KEY: '${{ secrets.PM2_PUBLIC_KEY }}' + JITSU_SERVER_URL: '${{ secrets.JITSU_SERVER_URL }}' + JITSU_SERVER_WRITE_KEY: '${{ secrets.JITSU_SERVER_WRITE_KEY }}' + OTEL_ENABLED: '${{ secrets.OTEL_ENABLED }}' + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '${{ secrets.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT }}' + OTEL_EXPORTER_OTLP_HEADERS: '${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}' + GAUZY_GITHUB_CLIENT_ID: '${{ secrets.GAUZY_GITHUB_CLIENT_ID }}' + GAUZY_GITHUB_CLIENT_SECRET: '${{ secrets.GAUZY_GITHUB_CLIENT_SECRET }}' + GAUZY_GITHUB_APP_PRIVATE_KEY: '${{ secrets.GAUZY_GITHUB_APP_PRIVATE_KEY }}' + GAUZY_GITHUB_WEBHOOK_URL: '${{ secrets.GAUZY_GITHUB_WEBHOOK_URL }}' + GAUZY_GITHUB_WEBHOOK_SECRET: '${{ secrets.GAUZY_GITHUB_WEBHOOK_SECRET }}' + GAUZY_GITHUB_APP_NAME: '${{ secrets.GAUZY_GITHUB_APP_NAME }}' + GAUZY_GITHUB_REDIRECT_URL: '${{ secrets.GAUZY_GITHUB_REDIRECT_URL }}' + GAUZY_GITHUB_POST_INSTALL_URL: '${{ secrets.GAUZY_GITHUB_POST_INSTALL_URL }}' + GAUZY_GITHUB_APP_ID: '${{ secrets.GAUZY_GITHUB_APP_ID }}' + GAUZY_GITHUB_OAUTH_CLIENT_ID: '${{ secrets.GAUZY_GITHUB_OAUTH_CLIENT_ID }}' + GAUZY_GITHUB_OAUTH_CLIENT_SECRET: '${{ secrets.GAUZY_GITHUB_OAUTH_CLIENT_SECRET }}' + GAUZY_GITHUB_OAUTH_CALLBACK_URL: '${{ secrets.GAUZY_GITHUB_OAUTH_CALLBACK_URL }}' + JITSU_BROWSER_URL: '${{ secrets.JITSU_BROWSER_URL }}' + JITSU_BROWSER_WRITE_KEY: '${{ secrets.JITSU_BROWSER_WRITE_KEY }}' + MAGIC_CODE_EXPIRATION_TIME: '${{ secrets.MAGIC_CODE_EXPIRATION_TIME }}' + APP_NAME: '${{ secrets.APP_NAME }}' + APP_LOGO: '${{ secrets.APP_LOGO }}' + APP_SIGNATURE: '${{ secrets.APP_SIGNATURE }}' + APP_LINK: '${{ secrets.APP_LINK }}' + APP_EMAIL_CONFIRMATION_URL: '${{ secrets.APP_EMAIL_CONFIRMATION_URL }}' + APP_MAGIC_SIGN_URL: '${{ secrets.APP_MAGIC_SIGN_URL }}' + COMPANY_LINK: '${{ secrets.COMPANY_LINK }}' + COMPANY_NAME: '${{ secrets.COMPANY_NAME }}' + + # we need this step because for now we just use :latest tag + # note: for production we will use different strategy later + - name: Restart Pods to pick up :latest tag version + run: | + kubectl --context do-sfo2-k8s-gauzy rollout restart deployment/ever-teams-prod-api diff --git a/.github/workflows/desktop.apps.yml b/.github/workflows/desktop.apps.yml index 55020a252..da9153a20 100644 --- a/.github/workflows/desktop.apps.yml +++ b/.github/workflows/desktop.apps.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v4 with: repository: 'ever-co/ever-gauzy' - ref: develop + ref: master - name: Install Node.js, NPM and Yarn uses: buildjet/setup-node@v3 @@ -108,7 +108,7 @@ jobs: uses: actions/checkout@v4 with: repository: 'ever-co/ever-gauzy' - ref: develop + ref: master - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v3 @@ -186,7 +186,7 @@ jobs: uses: actions/checkout@v4 with: repository: 'ever-co/ever-gauzy' - ref: develop + ref: master - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v3 diff --git a/.render/render.dev.yaml b/.render/render.dev.yaml index 44b0641b2..43c9791ca 100644 --- a/.render/render.dev.yaml +++ b/.render/render.dev.yaml @@ -12,9 +12,9 @@ services: - key: RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED value: false - key: NEXT_PUBLIC_GAUZY_API_SERVER_URL - value: https://apistage.gauzy.co + value: https://apidev.ever.team - key: GAUZY_API_SERVER_URL - value: https://apistage.gauzy.co/api + value: https://apidev.ever.team/api - key: NEXT_PUBLIC_GA_MEASUREMENT_ID sync: false - key: NEXT_PUBLIC_CAPTCHA_SITE_KEY diff --git a/Dockerfile b/Dockerfile index 8712f6f9a..ddf296336 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # Ever Teams Platform ARG NODE_VERSION=18.17.1 -ARG NEXT_PUBLIC_GAUZY_API_SERVER_URL=https://api.gauzy.co +ARG NEXT_PUBLIC_GAUZY_API_SERVER_URL=https://api.ever.team ARG NEXT_PUBLIC_GA_MEASUREMENT_ID ARG NEXT_PUBLIC_CAPTCHA_SITE_KEY ARG NEXT_PUBLIC_DISABLE_AUTO_REFRESH=false diff --git a/README.md b/README.md index e2f737957..836fc8283 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,11 @@ Note: Currently WIP, the screenshot is just a temporary picture :) ## 🔗 Links -- **** - Ever Teams Platform web application (not yet in production release) -- **** - Check more information about the Ever Teams platform at the official website (WIP). -- **** - Check more information about the Ever Gauzy Platform at the official website. +- **** - Ever® Teams™ Platform Web Application. +- **** - Ever® Teams™ Platform Demo Web Application. +- **** - Ever® Teams™ Platform Documentation (WIP). +- **** - Check more information about the Ever® Teams™ platform at the official website (WIP). +- **** - Check more information about the Ever® Gauzy™ Platform at the official website. - **** - Get more information about our company products. ## ⚡️ Our Open Platforms @@ -72,9 +74,10 @@ Ever® Teams™ Platform () is built on top of our Busine - [NextJs](https://nextjs.org) - [React](https://reactjs.org) - [React Native](https://reactnative.dev) -- [Tailwind](https://tailwindcss.com/) - CSS / Styles -- [shadcn/ui](https://ui.shadcn.com/) - Component Library -- [Vercel](https://vercel.com) - Hosting +- [Expo](https://expo.dev) +- [Tailwind](https://tailwindcss.com) - CSS / Styles +- [shadcn/ui](https://ui.shadcn.com), [Radix](https://www.radix-ui.com) and [HeadlessUI](https://headlessui.com) - Component Libraries +- [Vercel](https://vercel.com) and [DigitalOcean](https://www.digitalocean.com) - Hosting #### See also README.md and CREDITS.md files in relevant folders for lists of libraries and software included in the Platform, information about licenses, and other details @@ -95,13 +98,15 @@ Please refer to our official [Platform Documentation](https://docs.ever.team) (W 3. Run `yarn build:web` 4. Run `yarn start:web` -Note: by default, Ever Teams web frontend will be connected to our production [Ever Gauzy](https://github.com/ever-co/ever-gauzy) API endpoint . You can change it in environment variable `GAUZY_API_SERVER_URL`, see below how to run with a Self-hosted Backend. +Notes: + +- by default, Ever Teams web frontend will be connected to our production [Ever Gauzy API](https://github.com/ever-co/ever-gauzy) API endpoint . You can change it in environment variables `GAUZY_API_SERVER_URL` and `NEXT_PUBLIC_GAUZY_API_SERVER_URL`, see below how to run with a Self-hosted Backend. ### Run with a Self-hosted Backend 1. Download and run the Ever Gauzy Server setup () or run the server manually (see ). You can also run only Ever Gauzy APIs (manually), see . For getting starting instructions, it's best to check the Ever Gauzy [README](https://github.com/ever-co/ever-gauzy/blob/develop/README.md) file. 2. Clone this repo -3. After you get the API or Server running, make sure you set the environment variable `GAUZY_API_SERVER_URL` in Ever Teams .env file (see for example). +3. After you get the API or Server running, make sure you set the environment variables `GAUZY_API_SERVER_URL` and `NEXT_PUBLIC_GAUZY_API_SERVER_URL` in Ever Teams .env file (see for example). 4. Run `yarn install` 5. Run `yarn build:web` 6. Run `yarn start:web` diff --git a/apps/extensions/components/popup/Tasks.tsx b/apps/extensions/components/popup/Tasks.tsx index 8048d48b5..6fd75df7c 100644 --- a/apps/extensions/components/popup/Tasks.tsx +++ b/apps/extensions/components/popup/Tasks.tsx @@ -1,6 +1,5 @@ import classNames from 'classnames'; -import React, { useEffect, useRef, useState } from 'react'; -import { act } from 'react-dom/test-utils'; +import React, { useEffect, useState } from 'react'; import AppDropdown from '~components/shared/AppDropdown'; import { roundInput, textEllipsis } from '~misc/tailwindClasses'; @@ -135,7 +134,8 @@ const Tasks: React.FC = ({ port }) => { 'ml-2 bg-slate-900 text-white rounded p-2', isEmptyEstimate() && 'bg-slate-600' )} - onClick={addNewTask}> + onClick={addNewTask} + > Add Task )} diff --git a/apps/extensions/components/popup/Timer.tsx b/apps/extensions/components/popup/Timer.tsx index c776294b5..57341bed9 100644 --- a/apps/extensions/components/popup/Timer.tsx +++ b/apps/extensions/components/popup/Timer.tsx @@ -1,7 +1,6 @@ import classNames from 'classnames'; import React, { useEffect, useState } from 'react'; -import browser from '~misc/browser'; import { MessageTypesFromBackgroundEnum, MessageTypesToBackgroundEnum } from '~typescript/enums/MessageTypesEnum'; import { TimerStateEnum } from '~typescript/enums/TimerStateEnum'; import type { IPostMessage } from '~typescript/interfaces/PostMessage'; diff --git a/apps/extensions/popup.tsx b/apps/extensions/popup.tsx index ef70716ae..a5223f8bf 100644 --- a/apps/extensions/popup.tsx +++ b/apps/extensions/popup.tsx @@ -7,10 +7,7 @@ import Timer from '~components/popup/Timer'; import './style.css'; import browser from '~misc/browser'; -import { MessageTypesFromBackgroundEnum } from '~typescript/enums/MessageTypesEnum'; -import { TimerStateEnum } from '~typescript/enums/TimerStateEnum'; -import { IPostMessage } from '~typescript/interfaces/PostMessage'; -import { ITimerUpdate } from '~typescript/interfaces/TimerUpdate'; + function IndexPopup() { const [port, setPort] = useState(null); diff --git a/apps/mobile/.env.template b/apps/mobile/.env.template index f07c6ee3f..ca80410b5 100644 --- a/apps/mobile/.env.template +++ b/apps/mobile/.env.template @@ -1,7 +1,7 @@ # NOTE: do NOT ever put here any secure settings! (e.g. Secret Keys) # We are using react-native-dotenv (.env) -GAUZY_API_URL=https://api.gauzy.co +GAUZY_API_URL=https://api.ever.team INVITE_CALLBACK_URL=https://app.ever.team/auth/passcode EXPO_PUBLIC_SENTRY_DSN= SENTRY_ORG=ever-co diff --git a/apps/mobile/app/components/Icon.tsx b/apps/mobile/app/components/Icon.tsx index f5e78bf7a..15aff471f 100644 --- a/apps/mobile/app/components/Icon.tsx +++ b/apps/mobile/app/components/Icon.tsx @@ -53,7 +53,7 @@ export function Icon(props: IconProps) { } = props; const isPressable = !!WrapperProps.onPress; - const Wrapper: ComponentType = WrapperProps?.onPress ? TouchableOpacity : View; + const Wrapper: ComponentType = WrapperProps && WrapperProps?.onPress ? TouchableOpacity : View; return ( { const body = { ...data, - ...registerDefaultValue, - } + ...registerDefaultValue + }; return serverFetch({ - path: "/auth/register", - method: "POST", - body, - }) -} + path: '/auth/register', + method: 'POST', + body + }); +}; export const loginUserRequest = (email: string, password: string) => { return serverFetch({ - path: "/auth/login", - method: "POST", + path: '/auth/login', + method: 'POST', body: { email, - password, - }, - }) -} + password + } + }); +}; export const whetherUserAuthenticatedRequest = (bearer_token: string) => { return serverFetch({ - path: "/user/authenticated", - method: "GET", - bearer_token, - }) -} + path: '/user/authenticated', + method: 'GET', + bearer_token + }); +}; type IUEmployeeParam = { - bearer_token: string - relations?: string[] -} + bearer_token: string; + relations?: string[]; +}; export const currentAuthenticatedUserRequest = ({ bearer_token, - relations = ["employee", "role", "tenant"], + relations = ['employee', 'role', 'tenant'] }: IUEmployeeParam) => { - const params = {} as { [x: string]: string } + const params = {} as { [x: string]: string }; relations.forEach((rl, i) => { - params[`relations[${i}]`] = rl - }) + params[`relations[${i}]`] = rl; + }); - const query = new URLSearchParams(params) + const query = new URLSearchParams(params); return serverFetch({ path: `/user/me?${query.toString()}`, - method: "GET", - bearer_token, - }) -} + method: 'GET', + bearer_token + }); +}; export const refreshTokenRequest = (refresh_token: string) => { return serverFetch<{ token: string }>({ - path: "/auth/refresh-token", - method: "POST", + path: '/auth/refresh-token', + method: 'POST', body: { - refresh_token, - }, - }) -} + refresh_token + } + }); +}; // auth/signin.email export function sendAuthCodeRequest(email: string) { - return serverFetch<{ status: number; message: string | "ok" }>({ - path: "/auth/signin.email", - method: "POST", - body: { email }, - }) + return serverFetch<{ status: number; message: string | 'ok' }>({ + path: '/auth/signin.email', + method: 'POST', + body: { email } + }); } // auth/signin.email/confirm Gives response with tenantId's export function verifyAuthCodeRequest(email: string, code: string) { return serverFetch({ - path: "/auth/signin.email/confirm?includeTeams=true", - method: "POST", - body: { email, code }, - }) + path: '/auth/signin.email/confirm?includeTeams=true', + method: 'POST', + body: { email, code } + }); } // auth/signin.workspace Need the email and the token from auth/signin.email/confirm export const signInWorkspaceRequest = (email: string, token: string) => { return serverFetch({ - path: "/auth/signin.workspace", - method: "POST", - body: { email, token }, - }) -} + path: '/auth/signin.workspace', + method: 'POST', + body: { email, token } + }); +}; export const verifyUserEmailByCodeRequest = (data: { - bearer_token: string - code: string - email: string - tenantId: string + bearer_token: string; + code: string; + email: string; + tenantId: string; }) => { - const { code, email, bearer_token, tenantId } = data + const { code, email, bearer_token, tenantId } = data; return serverFetch({ - path: "/auth/email/verify/code", - method: "POST", + path: '/auth/email/verify/code', + method: 'POST', body: { code, email, tenantId }, tenantId: data.tenantId, - bearer_token, - }) -} + bearer_token + }); +}; -export const resentVerifyUserLinkRequest = (data: { - bearer_token: string - email: string - tenantId: string -}) => { - const { email, bearer_token, tenantId } = data +export const resentVerifyUserLinkRequest = (data: { bearer_token: string; email: string; tenantId: string }) => { + const { email, bearer_token, tenantId } = data; return serverFetch({ - path: "/auth/email/verify/resend-link", - method: "POST", + path: '/auth/email/verify/resend-link', + method: 'POST', body: { email, tenantId }, tenantId: data.tenantId, - bearer_token, - }) -} + bearer_token + }); +}; diff --git a/apps/mobile/eas.json b/apps/mobile/eas.json index 0613e5925..6bcd4efad 100644 --- a/apps/mobile/eas.json +++ b/apps/mobile/eas.json @@ -30,7 +30,7 @@ "autoIncrement": true, "channel": "production", "env": { - "GAUZY_API_URL": "https://api.gauzy.co", + "GAUZY_API_URL": "https://api.ever.team", "INVITE_CALLBACK_URL": "https://app.ever.team/auth/passcode" } } diff --git a/apps/web/.env b/apps/web/.env index 539845cf2..e8d086fee 100644 --- a/apps/web/.env +++ b/apps/web/.env @@ -1,7 +1,7 @@ RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false -GAUZY_API_SERVER_URL=https://api.gauzy.co/api -NEXT_PUBLIC_GAUZY_API_SERVER_URL=https://api.gauzy.co +GAUZY_API_SERVER_URL=https://api.ever.team/api +NEXT_PUBLIC_GAUZY_API_SERVER_URL=https://api.ever.team NEXT_PUBLIC_GA_MEASUREMENT_ID= # CAPTCHA Settings diff --git a/apps/web/.env.sample b/apps/web/.env.sample index 61cbba1e7..30999081e 100644 --- a/apps/web/.env.sample +++ b/apps/web/.env.sample @@ -1,7 +1,7 @@ RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false -GAUZY_API_SERVER_URL=https://api.gauzy.co/api -NEXT_PUBLIC_GAUZY_API_SERVER_URL=https://api.gauzy.co +GAUZY_API_SERVER_URL=https://api.ever.team/api +NEXT_PUBLIC_GAUZY_API_SERVER_URL=https://api.ever.team NEXT_PUBLIC_GA_MEASUREMENT_ID= # CAPTCHA Settings diff --git a/apps/web/app/constants.ts b/apps/web/app/constants.ts index e27035a22..1fdd241e7 100644 --- a/apps/web/app/constants.ts +++ b/apps/web/app/constants.ts @@ -37,7 +37,8 @@ export const RECAPTCHA_SITE_KEY = getNextPublicEnv( export const RECAPTCHA_SECRET_KEY = process.env.CAPTCHA_SECRET_KEY; // Gauzy Server URL -export const GAUZY_API_SERVER_URL = process.env.GAUZY_API_SERVER_URL || 'https://api.gauzy.co/api'; +export const GAUZY_API_SERVER_URL = process.env.GAUZY_API_SERVER_URL || 'https://api.ever.team/api'; + export const GAUZY_API_BASE_SERVER_URL = getNextPublicEnv( 'NEXT_PUBLIC_GAUZY_API_SERVER_URL', process.env.NEXT_PUBLIC_GAUZY_API_SERVER_URL diff --git a/apps/web/app/helpers/regex.ts b/apps/web/app/helpers/regex.ts index 4bb2c47ac..876295bc4 100644 --- a/apps/web/app/helpers/regex.ts +++ b/apps/web/app/helpers/regex.ts @@ -5,4 +5,4 @@ export const VALID_HEX_COLOR = /^#(?:[0-9a-fA-F]{3,4}){1,2}$/; export const PHONE_REGEX = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/; export const URL_REGEX = - /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_+.~#?&//=]*)$/; + /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_+.~#?&/=]*)$/; diff --git a/apps/web/app/hooks/auth/useAuthenticationPasscode.ts b/apps/web/app/hooks/auth/useAuthenticationPasscode.ts index 9071e399d..412b8b548 100644 --- a/apps/web/app/hooks/auth/useAuthenticationPasscode.ts +++ b/apps/web/app/hooks/auth/useAuthenticationPasscode.ts @@ -78,7 +78,7 @@ export function useAuthenticationPasscode() { return; } - if (data?.workspaces && data.workspaces.length) { + if (data && Array.isArray(data.workspaces) && data.workspaces.length > 0) { setWorkspaces(data.workspaces); setScreen('workspace'); diff --git a/apps/web/app/hooks/features/usePublicOrganizationTeams.ts b/apps/web/app/hooks/features/usePublicOrganizationTeams.ts index 00707b079..442900927 100644 --- a/apps/web/app/hooks/features/usePublicOrganizationTeams.ts +++ b/apps/web/app/hooks/features/usePublicOrganizationTeams.ts @@ -71,7 +71,7 @@ export function usePublicOrganizationTeams() { } let responseTasks = (res.data.tasks as ITeamTask[]) || []; - if (responseTasks && responseTasks.length) { + if (Array.isArray(responseTasks) && responseTasks.length > 0) { responseTasks = responseTasks.map((task) => { const clone = cloneDeep(task); if (task.tags && task.tags?.length) { diff --git a/apps/web/app/services/client/api/public-organization-team.ts b/apps/web/app/services/client/api/public-organization-team.ts index a23d4c9ab..9c9707ac8 100644 --- a/apps/web/app/services/client/api/public-organization-team.ts +++ b/apps/web/app/services/client/api/public-organization-team.ts @@ -26,7 +26,7 @@ export function getPublicOrganizationTeamsAPI(profile_link: string, team_id: str params[`relations[${i}]`] = rl; }); - const queries = qs.stringify(params || {}); + const queries = qs.stringify(params); const endpoint = GAUZY_API_BASE_SERVER_URL.value ? `/public/team/${profile_link}/${team_id}?${queries}` @@ -48,7 +48,7 @@ export function getPublicOrganizationTeamsMiscDataAPI(profile_link: string, team params[`relations[${i}]`] = rl; }); - const queries = qs.stringify(params || {}); + const queries = qs.stringify(params); const endpoint = GAUZY_API_BASE_SERVER_URL.value ? `/public/team/${profile_link}/${team_id}?${queries}` diff --git a/apps/web/app/services/server/requests/public-organization-team.ts b/apps/web/app/services/server/requests/public-organization-team.ts index e53088927..da091a945 100644 --- a/apps/web/app/services/server/requests/public-organization-team.ts +++ b/apps/web/app/services/server/requests/public-organization-team.ts @@ -58,7 +58,7 @@ export function getPublicOrganizationTeamMiscDataRequest({ params[`relations[${i}]`] = rl; }); - const queries = qs.stringify(params || {}); + const queries = qs.stringify(params); return serverFetch({ path: `/public/team/${profileLink}/${teamId}?${queries.toString()}`, diff --git a/apps/web/app/services/server/requests/timer/timer-slot.ts b/apps/web/app/services/server/requests/timer/timer-slot.ts index 9ffc18b7e..9d3463822 100644 --- a/apps/web/app/services/server/requests/timer/timer-slot.ts +++ b/apps/web/app/services/server/requests/timer/timer-slot.ts @@ -61,5 +61,3 @@ export function deleteEmployeeTimeSlotsRequest({ tenantId }); } - -// https://apidemo.gauzy.co/api/timesheet/time-slot?ids[0]=71bde97d-f6e7-463a-90ef-c752072755ab&organizationId=0289f323-5aa5-4dc2-92c5-633f3e70ecb4&tenantId=ae69bf6c-072f-44cb-8f41-e981a3eccdb1 diff --git a/apps/web/lib/features/team-members.tsx b/apps/web/lib/features/team-members.tsx index 8fb91c684..1119ef926 100644 --- a/apps/web/lib/features/team-members.tsx +++ b/apps/web/lib/features/team-members.tsx @@ -25,7 +25,7 @@ export function TeamMembers({ publicTeam = false, kanbanView: view = IssuesView. const orderedMembers = [...members].sort((a, b) => (sortByWorkStatus(a, b) ? -1 : 1)); const blockViewMembers = - activeFilter == 'all' ? orderedMembers : orderedMembers.filter((m) => m.timerStatus === activeFilter) || []; + activeFilter == 'all' ? orderedMembers : orderedMembers.filter((m) => m.timerStatus === activeFilter); const currentUser = members.find((m) => m.employee.userId === user?.id); const $members = members diff --git a/apps/web/next.config.js b/apps/web/next.config.js index c47e96931..f3561a349 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -50,7 +50,10 @@ const nextConfig = { '127.0.0.1', 'cdn-icons-png.flaticon.com', // Remove this domain once the Backend Icons list is added 'api.gauzy.co', + 'apidev.gauzy.co', 'apistage.gauzy.co', + 'api.ever.team', + 'apidev.ever.team', 'gauzy.s3.wasabisys.com', 'gauzystage.s3.wasabisys.com' ] diff --git a/render.yaml b/render.yaml index 4a60baf46..9d3e8444c 100644 --- a/render.yaml +++ b/render.yaml @@ -12,9 +12,9 @@ services: - key: RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED value: false - key: NEXT_PUBLIC_GAUZY_API_SERVER_URL - value: https://api.gauzy.co + value: https://api.ever.team - key: GAUZY_API_SERVER_URL - value: https://api.gauzy.co/api + value: https://api.ever.team/api - key: NEXT_PUBLIC_GA_MEASUREMENT_ID sync: false - key: NEXT_PUBLIC_CAPTCHA_SITE_KEY