fitzee commented on code in PR #45524:
URL: https://github.com/apache/superset/pull/45524#discussion_r4330827191


##########
superset-frontend/src/features/semanticViews/AddSemanticViewModal.tsx:
##########
@@ -610,47 +623,65 @@ export default function AddSemanticViewModal({
           configuration: runtimeData,
         }));
 
-      const { json } = await SupersetClient.post({
-        endpoint: '/api/v1/semantic_view/',
-        jsonPayload: { views: viewsToCreate },
-      });
-
-      const created = Array.isArray(json?.result?.created)
-        ? json.result.created
-        : [];
-      const errors = Array.isArray(json?.result?.errors)
-        ? json.result.errors
-        : [];
+      let body: unknown;
+      try {
+        const { json } = await SupersetClient.post({
+          endpoint: '/api/v1/semantic_view/',
+          jsonPayload: { views: viewsToCreate },
+        });
+        body = json;
+      } catch (error) {
+        // SupersetClient rejects non-2xx responses before parsing their body.
+        if (
+          !isRecord(error) ||
+          error.status !== 422 ||
+          typeof error.json !== 'function'
+        ) {
+          throw error;
+        }
+        body = await error.json();
+      }
+      if (gen !== fetchGenRef.current) return;

Review Comment:
   non-blocking: Cancel/X stay enabled during save (`StandardModal` only 
disables the primary button), and closing bumps `fetchGenRef`, so this early 
return drops a response whose views were already committed server-side. Before 
this change the base code still called `onSuccess()`/toast after close; now the 
dataset list is not refreshed and the user gets no confirmation that anything 
was created (the new "closed and reopened" test asserts exactly this). Suggest 
skipping only the local state updates on a stale generation, but still calling 
`onSuccess()` (and the success toast) when `created.length > 0`.



##########
superset-frontend/src/features/semanticViews/AddSemanticViewModal.tsx:
##########
@@ -726,12 +757,32 @@ export default function AddSemanticViewModal({
       saveLoading={saving}
     >
       <ModalContent>
+        {creationErrors.length > 0 && (

Review Comment:
   non-blocking: `creationErrors` is cleared on layer change, close, and save, 
but not in `handleRuntimeFormChange`. After a partial failure, changing the 
source location (e.g. a different schema) replaces the views list while the 
alert still reports failures for views from the previous configuration. 
Clearing it when runtime data changes (or when the views list is refetched) 
avoids stale errors.



##########
superset-frontend/src/features/semanticViews/AddSemanticViewModal.tsx:
##########
@@ -726,12 +757,32 @@ export default function AddSemanticViewModal({
       saveLoading={saving}
     >
       <ModalContent>
+        {creationErrors.length > 0 && (
+          <Alert
+            type="error"
+            showIcon
+            message={t('Some semantic views could not be added')}
+            description={
+              <List

Review Comment:
   nit: no height bound. With a large batch failing (e.g. layer unreachable, 
100 selected views) the alert pushes the form far down the modal, and the toast 
concatenates all 100 names. A `max-height` + `overflow-y: auto` on the list, 
and truncating the toast name list ("a, b, c and 97 more"), would keep it 
usable.



##########
superset-frontend/src/features/semanticViews/AddSemanticViewModal.tsx:
##########
@@ -610,47 +623,65 @@ export default function AddSemanticViewModal({
           configuration: runtimeData,
         }));
 
-      const { json } = await SupersetClient.post({
-        endpoint: '/api/v1/semantic_view/',
-        jsonPayload: { views: viewsToCreate },
-      });
-
-      const created = Array.isArray(json?.result?.created)
-        ? json.result.created
-        : [];
-      const errors = Array.isArray(json?.result?.errors)
-        ? json.result.errors
-        : [];
+      let body: unknown;
+      try {
+        const { json } = await SupersetClient.post({
+          endpoint: '/api/v1/semantic_view/',
+          jsonPayload: { views: viewsToCreate },
+        });
+        body = json;
+      } catch (error) {
+        // SupersetClient rejects non-2xx responses before parsing their body.
+        if (
+          !isRecord(error) ||
+          error.status !== 422 ||
+          typeof error.json !== 'function'
+        ) {
+          throw error;
+        }
+        body = await error.json();
+      }
+      if (gen !== fetchGenRef.current) return;
+      const { created, errors } = parseCreationResult(body);
+      setCreationErrors(errors);
 
       if (created.length > 0) {
+        setAvailableViews(previous =>
+          previous.map(view =>
+            created.includes(view.name)
+              ? { ...view, already_added: true }
+              : view,
+          ),
+        );
+        setSelectedViewNames(previous =>
+          previous.filter(name => !created.includes(name)),
+        );
         addSuccessToast(t('%s semantic view(s) added', created.length));
+        onSuccess();
       }
 
       if (errors.length > 0) {
-        const failedNames = errors
-          .map((error: { name?: string }) => error?.name)
-          .filter((name: string | undefined): name is string => !!name);
+        const failedNames = errors.map(error => error.name).filter(Boolean);
         addDangerToast(
           failedNames.length > 0
             ? t(
                 '%s semantic view(s) failed to add: %s',
-                errors.length,
+                failedNames.length,

Review Comment:
   nit: switching from `errors.length` to `failedNames.length` undercounts when 
the server returns an error without a name (the API emits 
`view_data.get("name")`, which is `None` for a schema-invalid entry): two 
failures render as "1 semantic view(s) failed to add: customers". Counting 
server errors separately from the synthetic generic entry keeps the number 
accurate.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to