| @@ -1516,9 +1516,9 @@ | ||
| 1516 | 1516 | <div className="mt-4 p-4 bg-green-50 dark:bg-green-900/20 rounded-lg"> |
| 1517 | 1517 | <div className="flex items-center gap-2 mb-2"> |
| 1518 | 1518 | <CheckCircle className="w-5 h-5 text-green-600 dark:text-green-400" /> |
| 1519 | 1519 | <span className="text-sm font-medium text-green-700 dark:text-green-400"> |
| 1520 | - Import completed successfully! | |
| 1520 | + {__("Import completed successfully!", "yatra")} | |
| 1521 | 1521 | </span> |
| 1522 | 1522 | <button |
| 1523 | 1523 | onClick={async () => { |
| 1524 | 1524 | if (!importJob) return; |
| @@ -1538,19 +1538,61 @@ | ||
| 1538 | 1538 | <XCircle className="w-4 h-4" /> |
| 1539 | 1539 | </button> |
| 1540 | 1540 | </div> |
| 1541 | 1541 | |
| 1542 | - <div className="text-sm text-green-700 dark:text-green-400 mb-2"> | |
| 1543 | - Total: <strong>{importJob.processed_records}</strong>{" "} | |
| 1544 | - records imported | |
| 1545 | - </div> | |
| 1542 | + {(() => { | |
| 1543 | + // "0 imported" on its own reads as a failed import. A | |
| 1544 | + // re-import is supposed to bring in nothing: the rows are | |
| 1545 | + // already here and get skipped, which is the feature | |
| 1546 | + // working. Say so, rather than leaving a column of zeroes | |
| 1547 | + // and a red failure count to speak for themselves. | |
| 1548 | + const totals = Object.values( | |
| 1549 | + importJob.import_stats || {}, | |
| 1550 | + ).reduce( | |
| 1551 | + (acc: any, s: any) => ({ | |
| 1552 | + imported: acc.imported + (s.imported || 0), | |
| 1553 | + skipped: acc.skipped + (s.skipped || 0), | |
| 1554 | + failed: acc.failed + (s.failed || 0), | |
| 1555 | + }), | |
| 1556 | + { imported: 0, skipped: 0, failed: 0 }, | |
| 1557 | + ) as { imported: number; skipped: number; failed: number }; | |
| 1546 | 1558 | |
| 1559 | + return ( | |
| 1560 | + <div className="text-sm text-green-700 dark:text-green-400 mb-2"> | |
| 1561 | + <strong>{totals.imported}</strong>{" "} | |
| 1562 | + {__("imported", "yatra")} | |
| 1563 | + {totals.skipped > 0 && ( | |
| 1564 | + <> | |
| 1565 | + {", "} | |
| 1566 | + <strong>{totals.skipped}</strong>{" "} | |
| 1567 | + {__("already here", "yatra")} | |
| 1568 | + </> | |
| 1569 | + )} | |
| 1570 | + {totals.failed > 0 && ( | |
| 1571 | + <> | |
| 1572 | + {", "} | |
| 1573 | + <strong>{totals.failed}</strong>{" "} | |
| 1574 | + {__("could not be linked", "yatra")} | |
| 1575 | + </> | |
| 1576 | + )} | |
| 1577 | + {totals.imported === 0 && totals.skipped > 0 && ( | |
| 1578 | + <div className="text-xs mt-1"> | |
| 1579 | + {__( | |
| 1580 | + "Everything in this file was already on the site, so nothing was duplicated.", | |
| 1581 | + "yatra", | |
| 1582 | + )} | |
| 1583 | + </div> | |
| 1584 | + )} | |
| 1585 | + </div> | |
| 1586 | + ); | |
| 1587 | + })()} | |
| 1588 | + | |
| 1547 | 1589 | {/* Detailed statistics by data type */} |
| 1548 | 1590 | {importJob.import_stats && |
| 1549 | 1591 | Object.keys(importJob.import_stats).length > 0 && ( |
| 1550 | 1592 | <div className="mt-2 border-t border-green-200 dark:border-green-800 pt-2"> |
| 1551 | 1593 | <div className="text-xs font-medium text-green-700 dark:text-green-400 mb-2"> |
| 1552 | - Import Details: | |
| 1594 | + {__("Import Details:", "yatra")} | |
| 1553 | 1595 | </div> |
| 1554 | 1596 | <div className="grid grid-cols-1 gap-1"> |
| 1555 | 1597 | {Object.entries(importJob.import_stats).map( |
| 1556 | 1598 | ([dataType, stats]: [string, any]) => { |
| @@ -1567,9 +1609,9 @@ | ||
| 1567 | 1609 | > |
| 1568 | 1610 | <div className="flex items-center gap-1"> |
| 1569 | 1611 | <Icon className="w-3 h-3 text-green-600 dark:text-green-400" /> |
| 1570 | 1612 | <span className="capitalize"> |
| 1571 | - {dataType.replace("_", " ")}: | |
| 1613 | + {dataType.replace(/_/g, " ")}: | |
| 1572 | 1614 | </span> |
| 1573 | 1615 | </div> |
| 1574 | 1616 | <div> |
| 1575 | 1617 | <span className="text-green-700 dark:text-green-400"> |
| @@ -1574,11 +1616,30 @@ | ||
| 1574 | 1616 | <div> |
| 1575 | 1617 | <span className="text-green-700 dark:text-green-400"> |
| 1576 | 1618 | {stats.imported} |
| 1577 | 1619 | </span> |
| 1620 | + {stats.skipped > 0 && ( | |
| 1621 | + <span | |
| 1622 | + className="text-gray-500 dark:text-gray-400 ml-1" | |
| 1623 | + title={__( | |
| 1624 | + "Already present on this site, so not imported again", | |
| 1625 | + "yatra", | |
| 1626 | + )} | |
| 1627 | + > | |
| 1628 | + ({stats.skipped}{" "} | |
| 1629 | + {__("already here", "yatra")}) | |
| 1630 | + </span> | |
| 1631 | + )} | |
| 1578 | 1632 | {stats.failed > 0 && ( |
| 1579 | - <span className="text-red-600 dark:text-red-400 ml-1"> | |
| 1580 | - ({stats.failed} failed) | |
| 1633 | + <span | |
| 1634 | + className="text-amber-600 dark:text-amber-400 ml-1" | |
| 1635 | + title={__( | |
| 1636 | + "These rows point at a record the export file does not contain — usually something deleted on the original site — so there was nothing to attach them to.", | |
| 1637 | + "yatra", | |
| 1638 | + )} | |
| 1639 | + > | |
| 1640 | + ({stats.failed}{" "} | |
| 1641 | + {__("not linked", "yatra")}) | |
| 1581 | 1642 | </span> |
| 1582 | 1643 | )} |
| 1583 | 1644 | </div> |
| 1584 | 1645 | </div> |
| @@ -1863,9 +1924,9 @@ | ||
| 1863 | 1924 | className="flex items-center justify-between" |
| 1864 | 1925 | > |
| 1865 | 1926 | <div> |
| 1866 | 1927 | <span className="font-medium capitalize"> |
| 1867 | - {key.replace("_", " ")} | |
| 1928 | + {key.replace(/_/g, " ")} | |
| 1868 | 1929 | </span> |
| 1869 | 1930 | <div className="text-sm text-gray-600 dark:text-gray-400"> |
| 1870 | 1931 | Required: {req.required} | Current: {req.current} |
| 1871 | 1932 | </div> |