Merged PR 2176: update formatting

update formatting

Related work items: #22012
This commit is contained in:
Robert Bond
2026-03-17 09:24:41 +00:00
2 changed files with 158 additions and 132 deletions
+105 -97
View File
@@ -5,7 +5,7 @@ import { PrismaClient } from "@prisma/client";
import CryptoJS from "crypto-js"; import CryptoJS from "crypto-js";
import { getUpToLastSlash, streamToString } from "../utils/adminHelper"; import { getUpToLastSlash, streamToString } from "../utils/adminHelper";
import { listContainersForUser } from "../../../actions/azurestorage"; import { listContainersForUser } from "../../../actions/azurestorage";
import pLimit from "p-limit";
const prisma = global.prisma || new PrismaClient(); const prisma = global.prisma || new PrismaClient();
const WORDKEY = process.env.HASHKEY; const WORDKEY = process.env.HASHKEY;
/** /**
@@ -34,112 +34,120 @@ export async function fetchAdminStorageData() {
const users = await prisma.user.findMany(); const users = await prisma.user.findMany();
const limit = pLimit(5);
let data = await Promise.all( let data = await Promise.all(
users.map(async (user) => { users.map(async (user) => {
const containers = await listContainersForUser( limit(async () => {
blobServiceClient, const containers = await listContainersForUser(
`${user.id}`, blobServiceClient,
user.email `${user.id}`,
); user.email
);
const containersWithHashes = await Promise.all( const containersWithHashes = await Promise.all(
containers.map(async (container) => { containers.map(async (container) => {
const groupedByFolder = await container.blobs.reduce( const groupedByFolder = await container.blobs.reduce(
async (accP, blob) => { async (accP, blob) => {
const acc = await accP; const acc = await accP;
const folderPath = const folderPath =
getUpToLastSlash(blob.name.trim()) || ""; getUpToLastSlash(blob.name.trim()) || "";
const hashedfilepath = hashAPIPath( const hashedfilepath = hashAPIPath(
`/api/file/downloadblob?container=${ `/api/file/downloadblob?container=${
container.container
}&casefolderID=${folderPath}&blobname=${blob.name
.substring(blob.name.lastIndexOf("/") + 1)
.trim()}`,
process.env.HASHKEY
);
const fileNameOnly = blob.name.substring(
blob.name.lastIndexOf("/") + 1
);
const isTmpFile = fileNameOnly.startsWith("TMP-");
const blobWithHash = {
...blob,
hashedfilepath,
isTmpFile
};
let folderGroup = acc.find(
(f) => f.folderPath === folderPath
);
if (!folderGroup) {
folderGroup = {
folderPath,
blobs: [],
hasRepJson: false,
repJsonBlob: null,
repComplete: false,
hasTmpFile: false
};
acc.push(folderGroup);
}
folderGroup.blobs.push(blobWithHash);
if (isTmpFile) {
folderGroup.hasTmpFile = true;
}
// rep.json handling
if (blob.name.toLowerCase().endsWith("rep.json")) {
folderGroup.hasRepJson = true;
folderGroup.repJsonBlob = blobWithHash;
const containerClient =
blobServiceClient.getContainerClient(
container.container container.container
); }&casefolderID=${folderPath}&blobname=${blob.name
const blockBlobClient = .substring(
containerClient.getBlockBlobClient( blob.name.lastIndexOf("/") + 1
blob.name )
); .trim()}`,
process.env.HASHKEY
);
try { const fileNameOnly = blob.name.substring(
const downloadResponse = blob.name.lastIndexOf("/") + 1
await blockBlobClient.download(0); );
const downloaded = await streamToString( const isTmpFile =
downloadResponse.readableStreamBody fileNameOnly.startsWith("TMP-");
);
const json = JSON.parse(downloaded); const blobWithHash = {
folderGroup.repComplete = Boolean( ...blob,
json.repComplete hashedfilepath,
); isTmpFile
} catch (err) { };
console.error(
"Error reading rep.json", let folderGroup = acc.find(
err (f) => f.folderPath === folderPath
); );
folderGroup.repComplete = false; if (!folderGroup) {
folderGroup = {
folderPath,
blobs: [],
hasRepJson: false,
repJsonBlob: null,
repComplete: false,
hasTmpFile: false
};
acc.push(folderGroup);
} }
}
return acc; folderGroup.blobs.push(blobWithHash);
},
Promise.resolve([])
);
return { ...container, folders: groupedByFolder }; if (isTmpFile) {
}) folderGroup.hasTmpFile = true;
); }
return containersWithHashes.length > 0 // rep.json handling
? { if (
id: user.id, blob.name.toLowerCase().endsWith("rep.json")
email: user.email, ) {
containers: containersWithHashes folderGroup.hasRepJson = true;
} folderGroup.repJsonBlob = blobWithHash;
: null;
const containerClient =
blobServiceClient.getContainerClient(
container.container
);
const blockBlobClient =
containerClient.getBlockBlobClient(
blob.name
);
try {
const downloadResponse =
await blockBlobClient.download(0);
const downloaded = await streamToString(
downloadResponse.readableStreamBody
);
const json = JSON.parse(downloaded);
folderGroup.repComplete = Boolean(
json.repComplete
);
} catch (err) {
console.error(
"Error reading rep.json",
err
);
folderGroup.repComplete = false;
}
}
return acc;
},
Promise.resolve([])
);
return { ...container, folders: groupedByFolder };
})
);
return containersWithHashes.length > 0
? {
id: user.id,
email: user.email,
containers: containersWithHashes
}
: null;
});
}) })
); );
+53 -35
View File
@@ -112,7 +112,8 @@ export const AppealRow_pdf = (props) => {
color: "grey" color: "grey"
}, },
documentList: { documentList: {
fontSize: 10 fontSize: 10,
lineHeight: 1.4
}, },
richArea: { richArea: {
fontSize: 12, fontSize: 12,
@@ -432,51 +433,68 @@ export const AppealRow_pdf = (props) => {
flexDirection: "column", flexDirection: "column",
marginBottom: 10 marginBottom: 10
}} }}
wrap={false}
> >
<View <View
wrap={false}
style={{ style={{
flexDirection: "row", flexDirection: "column",
marginBottom: 10 marginBottom: 10
}} }}
> >
<Text {/* Removed wrap={false} here so the list can flow to page 2 */}
<View
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text
style={
styles.questionTextWide
}
>
{rows[0].value}
</Text>
</View>
<View
style={ style={
styles.questionTextWide styles.questionAnswerWide
} }
> >
{rows[0].value} {blobList.map((blob, i) => {
</Text> const isTargetType =
</View> getDocumentTypeFromFilename(
<View blob.name
style={ ) ===
styles.questionAnswerWide
}
>
{blobList.map((blob, i) => (
<Text key={i}>
{getDocumentTypeFromFilename(
blob.name
) ===
documentTypeCode[0] documentTypeCode[0]
.value && ( .value;
<Text
style={ if (!isTargetType)
styles.documentList return null;
}
return (
/* wrap={false} here ensures a single filename stays together */
<View
key={i}
wrap={false}
style={{
marginBottom: 4
}}
> >
{blob.name} <Text
{blob?.size && style={
" - " + styles.documentList
bytesToSize( }
blob?.size >
)}{" "} {blob.name}
{"\n"} {blob?.size &&
</Text> ` - ${bytesToSize(blob.size)}`}
)} </Text>
</Text> </View>
))} );
})}
</View>
</View> </View>
</View> </View>
); );