@rebasepro/app 0.21.1 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,9 +6,9 @@
6
6
  *
7
7
  * The reason this is a pure function rather than logic inside the form is that
8
8
  * the *defaults* are the interesting part. A collection that never writes an
9
- * `admin.form` block still has to get a two-column layout out of this — the flat
10
- * run of full-width fields it produced before was the single biggest cost in the
11
- * form, and no amount of config would have fixed it for collections nobody
9
+ * `admin.form` block still has to get a two-column layout out of this once it is
10
+ * long enough to need one — the flat run of full-width fields it produced before
11
+ * was the single biggest cost in the form, and no amount of config would have fixed it for collections nobody
12
12
  * hand-tunes. Deriving it here means it is testable in isolation, which matters
13
13
  * because "what span does a date get" is exactly the kind of rule that rots.
14
14
  */
@@ -0,0 +1,16 @@
1
+ /**
2
+ * What the login screen says about a refused sign-in.
3
+ *
4
+ * The server's message is written for whoever reads the API response, and some
5
+ * of them are instructions for a developer. A Google sign-in onto an address
6
+ * that already has an unverified password account used to put this in front of
7
+ * the visitor:
8
+ *
9
+ * … Sign in with your existing method, then POST to /auth/link/google to
10
+ * link google to your account.
11
+ *
12
+ * So the codes a person can act on get the screen's own, translated words, and
13
+ * every other error keeps the server's message, which is still the most
14
+ * specific thing there is to show.
15
+ */
16
+ export declare function authErrorMessage(error: unknown, t: (key: string) => string): string;
package/dist/index.es.js CHANGED
@@ -2614,8 +2614,9 @@ function useComponentOverride(name, DefaultComponent) {
2614
2614
  return useMemo(() => {
2615
2615
  const override = collectionOverrides[name] ?? globalOverrides[name];
2616
2616
  if (!override) return DefaultComponent;
2617
+ const UserComponent = resolveComponentRef(override.Component);
2618
+ if (!UserComponent) return DefaultComponent;
2617
2619
  if (override.wrap) {
2618
- const UserComponent = override.Component;
2619
2620
  const Wrapper = (props) => /* @__PURE__ */ jsx(UserComponent, {
2620
2621
  ...props,
2621
2622
  OriginalComponent: DefaultComponent
@@ -2623,7 +2624,7 @@ function useComponentOverride(name, DefaultComponent) {
2623
2624
  Wrapper.displayName = `Wrapped(${name})`;
2624
2625
  return Wrapper;
2625
2626
  }
2626
- return override.Component;
2627
+ return UserComponent;
2627
2628
  }, [
2628
2629
  collectionOverrides,
2629
2630
  globalOverrides,
@@ -4430,7 +4431,7 @@ function UserRow({ user, isSelected, isSelf, onClick }) {
4430
4431
  }) : /* @__PURE__ */ jsx("div", {
4431
4432
  className: "w-7 h-7 rounded-full bg-surface-raised flex items-center justify-center shrink-0",
4432
4433
  children: /* @__PURE__ */ jsx(CircleUserIcon, {
4433
- size: "smallest",
4434
+ size: iconSize.smallest,
4434
4435
  className: "text-text-disabled dark:text-text-disabled-dark"
4435
4436
  })
4436
4437
  }),
@@ -4634,6 +4635,27 @@ function consumeOAuthCallback(search, storage = defaultStorage(), now = Date.now
4634
4635
  };
4635
4636
  }
4636
4637
  //#endregion
4638
+ //#region src/components/LoginView/auth-error-message.ts
4639
+ /**
4640
+ * What the login screen says about a refused sign-in.
4641
+ *
4642
+ * The server's message is written for whoever reads the API response, and some
4643
+ * of them are instructions for a developer. A Google sign-in onto an address
4644
+ * that already has an unverified password account used to put this in front of
4645
+ * the visitor:
4646
+ *
4647
+ * … Sign in with your existing method, then POST to /auth/link/google to
4648
+ * link google to your account.
4649
+ *
4650
+ * So the codes a person can act on get the screen's own, translated words, and
4651
+ * every other error keeps the server's message, which is still the most
4652
+ * specific thing there is to show.
4653
+ */
4654
+ function authErrorMessage(error, t) {
4655
+ if (error instanceof Error && "code" in error && error.code === "EMAIL_NOT_VERIFIED") return ("details" in error && typeof error.details === "object" && error.details !== null && "reason" in error.details ? error.details.reason : void 0) === "local-account-unverified" ? t("auth_account_exists_sign_in_with_password") : t("auth_account_exists_with_different_credential");
4656
+ return error instanceof Error ? error.message : String(error);
4657
+ }
4658
+ //#endregion
4637
4659
  //#region src/components/LoginView/LoginView.tsx
4638
4660
  /**
4639
4661
  * The shared field background mixin (`dark:bg-black/30`) is invisible on the
@@ -4768,7 +4790,7 @@ function LoginView({ logo, authController, noUserComponent, disableSignupScreen
4768
4790
  alt: "Logo"
4769
4791
  });
4770
4792
  else logoComponent = /* @__PURE__ */ jsx(RebaseLogo, {});
4771
- const controllerError = authController.authProviderError && !authController.user ? authController.authProviderError instanceof Error ? authController.authProviderError.message : String(authController.authProviderError) : null;
4793
+ const controllerError = authController.authProviderError && !authController.user ? authErrorMessage(authController.authProviderError, t) : null;
4772
4794
  const buttonsErrorMessage = providerError ?? controllerError;
4773
4795
  let notAllowedMessage;
4774
4796
  if (notAllowedError) if (typeof notAllowedError === "string") notAllowedMessage = notAllowedError;
@@ -5141,7 +5163,7 @@ function LoginForm({ onClose, onForgotPassword, authController, registrationMode
5141
5163
  if (!err || authController.user) return null;
5142
5164
  return /* @__PURE__ */ jsx("div", {
5143
5165
  className: "w-full mb-2",
5144
- children: /* @__PURE__ */ jsx(ErrorView, { error: err instanceof Error ? err.message : String(err) })
5166
+ children: /* @__PURE__ */ jsx(ErrorView, { error: authErrorMessage(err, t) })
5145
5167
  });
5146
5168
  })(),
5147
5169
  /* @__PURE__ */ jsx(Typography, {
@@ -6013,7 +6035,8 @@ var en = {
6013
6035
  auth_user_not_found: "User not found",
6014
6036
  auth_wrong_password: "Wrong password. Please try again.",
6015
6037
  auth_user_disabled: "User disabled. Please contact support.",
6016
- auth_account_exists_with_different_credential: "Account exists with different sign in method",
6038
+ auth_account_exists_with_different_credential: "An account with this email already exists. Sign in the way you did before.",
6039
+ auth_account_exists_sign_in_with_password: "An account with this email already exists. Sign in with your email and password instead.",
6017
6040
  auth_email_already_in_use: "The email is already in use",
6018
6041
  auth_google_permissions_required: "You need to grant additional permissions in order to manage your Google Cloud projects",
6019
6042
  auth_invalid_email_password: "Please enter both email and password",
@@ -7029,7 +7052,8 @@ var es = {
7029
7052
  auth_user_not_found: "Usuario no encontrado",
7030
7053
  auth_wrong_password: "Contraseña incorrecta. Por favor, inténtalo de nuevo.",
7031
7054
  auth_user_disabled: "Usuario deshabilitado. Por favor, contacta con soporte.",
7032
- auth_account_exists_with_different_credential: "Ya existe una cuenta con un método de inicio de sesión diferente",
7055
+ auth_account_exists_with_different_credential: "Ya existe una cuenta con este correo electrónico. Inicia sesión como lo hiciste la última vez.",
7056
+ auth_account_exists_sign_in_with_password: "Ya existe una cuenta con este correo electrónico. Inicia sesión con tu correo electrónico y contraseña.",
7033
7057
  auth_email_already_in_use: "El correo electrónico ya está en uso",
7034
7058
  auth_google_permissions_required: "Necesitas conceder permisos adicionales para gestionar tus proyectos de Google Cloud",
7035
7059
  auth_invalid_email_password: "Por favor introduce tanto el correo electrónico como la contraseña",
@@ -8037,7 +8061,8 @@ var de = {
8037
8061
  auth_user_not_found: "Benutzer nicht gefunden",
8038
8062
  auth_wrong_password: "Falsches Passwort. Bitte versuchen Sie es erneut.",
8039
8063
  auth_user_disabled: "Benutzer deaktiviert. Bitte kontaktieren Sie den Support.",
8040
- auth_account_exists_with_different_credential: "Konto existiert mit anderer Anmeldemethode",
8064
+ auth_account_exists_with_different_credential: "Mit dieser E-Mail-Adresse existiert bereits ein Konto. Melden Sie sich so an wie beim letzten Mal.",
8065
+ auth_account_exists_sign_in_with_password: "Mit dieser E-Mail-Adresse existiert bereits ein Konto. Melden Sie sich stattdessen mit E-Mail und Passwort an.",
8041
8066
  auth_email_already_in_use: "Die E-Mail wird bereits verwendet",
8042
8067
  auth_google_permissions_required: "Sie müssen zusätzliche Berechtigungen erteilen, um Ihre Google Cloud-Projekte verwalten zu können",
8043
8068
  auth_invalid_email_password: "Bitte geben Sie sowohl E-Mail als auch Passwort ein",
@@ -9045,7 +9070,8 @@ var fr = {
9045
9070
  auth_user_not_found: "Utilisateur non trouvé",
9046
9071
  auth_wrong_password: "Mot de passe erroné. Veuillez réessayer.",
9047
9072
  auth_user_disabled: "Utilisateur désactivé. Veuillez contacter le support.",
9048
- auth_account_exists_with_different_credential: "Un compte existe avec une méthode de connexion différente",
9073
+ auth_account_exists_with_different_credential: "Un compte existe déjà avec cet e-mail. Connectez-vous comme la dernière fois.",
9074
+ auth_account_exists_sign_in_with_password: "Un compte existe déjà avec cet e-mail. Connectez-vous plutôt avec votre e-mail et votre mot de passe.",
9049
9075
  auth_email_already_in_use: "L'e-mail est déjà utilisé",
9050
9076
  auth_google_permissions_required: "Vous devez accorder des autorisations supplémentaires afin de gérer vos projets Google Cloud",
9051
9077
  auth_invalid_email_password: "Veuillez entrer l'e-mail et le mot de passe",
@@ -10053,7 +10079,8 @@ var it = {
10053
10079
  auth_user_not_found: "Utente non trovato",
10054
10080
  auth_wrong_password: "Password errata",
10055
10081
  auth_user_disabled: "Account disabilitato",
10056
- auth_account_exists_with_different_credential: "Esiste già un account con questo indirizzo email ma con credenziali diverse",
10082
+ auth_account_exists_with_different_credential: "Esiste già un account con questo indirizzo email. Accedi come hai fatto l'ultima volta.",
10083
+ auth_account_exists_sign_in_with_password: "Esiste già un account con questo indirizzo email. Accedi con email e password.",
10057
10084
  auth_email_already_in_use: "Questo indirizzo email è già in uso",
10058
10085
  auth_google_permissions_required: "Sono necessarie le autorizzazioni di Google",
10059
10086
  auth_invalid_email_password: "Email o password non valide",
@@ -11061,7 +11088,8 @@ var hi = {
11061
11088
  auth_user_not_found: "उपयोगकर्ता नहीं मिला",
11062
11089
  auth_wrong_password: "गलत पासवर्ड। कृपया पुनः प्रयास करें।",
11063
11090
  auth_user_disabled: "उपयोगकर्ता अक्षम है। कृपया समर्थन से संपर्क करें।",
11064
- auth_account_exists_with_different_credential: "विभिन्न साइन-इन विधि के साथ खाता मौजूद है",
11091
+ auth_account_exists_with_different_credential: "इस ईमेल से एक खाता पहले से मौजूद है। पिछली बार की तरह साइन इन करें।",
11092
+ auth_account_exists_sign_in_with_password: "इस ईमेल से एक खाता पहले से मौजूद है। इसके बजाय अपने ईमेल और पासवर्ड से साइन इन करें।",
11065
11093
  auth_email_already_in_use: "ईमेल पहले से ही उपयोग में है",
11066
11094
  auth_google_permissions_required: "अपने Google Cloud प्रोजेक्ट प्रबंधित करने के लिए आपको अतिरिक्त अनुमतियाँ देने की आवश्यकता है",
11067
11095
  auth_invalid_email_password: "कृपया ईमेल और पासवर्ड दोनों दर्ज करें",
@@ -12074,7 +12102,8 @@ var pt = {
12074
12102
  auth_user_not_found: "Utilizador não encontrado",
12075
12103
  auth_wrong_password: "Palavra-passe incorreta. Por favor tente novamente.",
12076
12104
  auth_user_disabled: "Utilizador desativado. Por favor contacte o suporte.",
12077
- auth_account_exists_with_different_credential: "Conta existente com método de início de sessão diferente",
12105
+ auth_account_exists_with_different_credential: "Já existe uma conta com este email. Inicie sessão como fez da última vez.",
12106
+ auth_account_exists_sign_in_with_password: "Já existe uma conta com este email. Inicie sessão com o seu email e palavra-passe.",
12078
12107
  auth_email_already_in_use: "O email já está em uso",
12079
12108
  auth_google_permissions_required: "Precisa de conceder permissões adicionais para gerir os seus projetos Google Cloud",
12080
12109
  auth_invalid_email_password: "Por favor introduza o email e a palavra-passe",
@@ -14530,6 +14559,17 @@ function resolveFilterOperators({ property, isArray, engine }) {
14530
14559
  * number by definition.
14531
14560
  */
14532
14561
  var GRID_COLUMNS = 4;
14562
+ /**
14563
+ * The most fields a form can hold and still be laid out as one column.
14564
+ *
14565
+ * Columns are a density tool: they buy back height on a form long enough to
14566
+ * scroll. A form this short fits on any surface without scrolling, so pairing
14567
+ * its fields buys nothing and costs the reading order — the eye zig-zags across
14568
+ * values that are next to each other only because of their types. The users
14569
+ * form was the case that showed it: Email beside Name, then Roles alone on the
14570
+ * row below, in a dialog with room to spare.
14571
+ */
14572
+ var SINGLE_COLUMN_MAX_FIELDS = 4;
14533
14573
  /** Does this property's editor need the full width of the column? */
14534
14574
  function needsFullWidth(property) {
14535
14575
  switch (property.type) {
@@ -14718,10 +14758,14 @@ function resolveFormLayout({ collection, fieldKeys, status }) {
14718
14758
  collapsed: false,
14719
14759
  fields: leftovers
14720
14760
  });
14761
+ const singleColumn = sections.reduce((sum, section) => sum + section.fields.length, 0) <= SINGLE_COLUMN_MAX_FIELDS;
14721
14762
  return {
14722
14763
  sections: sections.filter((s) => s.fields.length > 0).map((s) => ({
14723
14764
  ...s,
14724
- fields: fillRows(s.fields)
14765
+ fields: fillRows(singleColumn ? s.fields.map((f) => f.spanExplicit ? f : {
14766
+ ...f,
14767
+ span: GRID_COLUMNS
14768
+ }) : s.fields)
14725
14769
  })),
14726
14770
  sidebar,
14727
14771
  showRecordMeta,