mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 03:14:23 +00:00
some fixes and lint cleanups
This commit is contained in:
@@ -22,9 +22,6 @@ import os
|
||||
import sys
|
||||
|
||||
bonsai_lib_path = os.environ.get("BONSAI_LIB_PATH")
|
||||
print(os.environ)
|
||||
print(bonsai_lib_path)
|
||||
bonsai_version = os.environ.get("BONSAI_VERSION")
|
||||
|
||||
if bonsai_lib_path:
|
||||
sys.path.insert(0, bonsai_lib_path)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"wasm": {
|
||||
"wheel_url": "/worker/bin/ifcopenshell-0.8.3+bb329af-cp313-cp313-emscripten_4_0_9_wasm32.whl",
|
||||
"odfpy_url": "/worker/bin/odfpy-1.4.2-py2.py3-none-any.whl",
|
||||
"api_py_url": "/worker/api.py",
|
||||
"pyodide_url": "https://cdn.jsdelivr.net/pyodide/v0.28.0/full/pyodide.js"
|
||||
"api_py_url": "/worker/api.py"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,17 +265,17 @@ export async function deleteFacet(
|
||||
const spec = Module.documents[docId].specifications.specification[specId];
|
||||
const list = (spec[clause] as Record<string, unknown> | undefined)?.[facet] as Facet[] | undefined;
|
||||
if (!list) return;
|
||||
delete list[facetId];
|
||||
list.splice(facetId, 1);
|
||||
}
|
||||
|
||||
export function getSpecUsage(spec?: Specification | null): IdsCardinality {
|
||||
if (!spec?.applicability) return 'required';
|
||||
const minOccurs = spec.applicability["@minOccurs"] as number | undefined;
|
||||
const maxOccurs = spec.applicability["@maxOccurs"] as number | "unbounded" | undefined;
|
||||
|
||||
if (minOccurs === 1 && maxOccurs === "unbounded") return 'required';
|
||||
if (minOccurs === 0 && maxOccurs === "unbounded") return 'optional';
|
||||
if (minOccurs === 0 && maxOccurs === 0) return 'prohibited';
|
||||
|
||||
if (minOccurs !== 0) return 'required';
|
||||
if (minOccurs === 0 && maxOccurs !== 0) return 'optional';
|
||||
if (maxOccurs === 0) return 'prohibited';
|
||||
return 'required';
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
(facet as Record<string, unknown>)[prop] = value;
|
||||
};
|
||||
|
||||
const baseId = `facet-${facetType}-${index}`;
|
||||
let baseId = $derived(`facet-${facetType}-${index}`);
|
||||
</script>
|
||||
|
||||
<div class="restriction-item">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { error, success } from "$src/modules/utils/toast.svelte";
|
||||
import * as Tooltip from "$src/lib/components/ui/tooltip";
|
||||
import type { AuditReport, AuditReportData } from "$src/types/report";
|
||||
import type { DocumentState, IdsDocument } from "$src/types/ids";
|
||||
import type { DocumentState, IdsDocument, Specification } from "$src/types/ids";
|
||||
|
||||
let activeDocument = $derived(
|
||||
IDS.Module.activeDocument ? (IDS.Module.documents[IDS.Module.activeDocument] as IdsDocument) : null
|
||||
@@ -19,6 +19,8 @@
|
||||
let expandedRequirements = $state(new Set<string>());
|
||||
let allExpanded = $state(false);
|
||||
|
||||
type SpecificationStatus = boolean | 'skipped' | null;
|
||||
|
||||
// Open Editor mode and jump to a specific specification
|
||||
function editSpecification(index: number) {
|
||||
if (IDS.Module.activeDocument) {
|
||||
@@ -55,7 +57,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
function getSpecificationStatus(specIndex: number, auditData: AuditReportData) {
|
||||
function getSpecificationStatus(specIndex: number, auditData: AuditReportData): SpecificationStatus {
|
||||
const spec = auditData.specifications[specIndex];
|
||||
if (!spec) return null;
|
||||
return spec.is_skipped ? 'skipped' : spec.status;
|
||||
@@ -98,6 +100,10 @@
|
||||
return null; // No reason needed for passed specifications
|
||||
}
|
||||
|
||||
function getDocumentSpecificationUsage(spec: Specification) {
|
||||
return IDS.getSpecUsage(spec);
|
||||
}
|
||||
|
||||
async function handleDownloadReport() {
|
||||
if (!auditReport) return;
|
||||
|
||||
@@ -223,6 +229,7 @@
|
||||
</button>
|
||||
</div>
|
||||
{#each activeDocument.specifications.specification as spec, index}
|
||||
{@const usage = getDocumentSpecificationUsage(spec)}
|
||||
<div class="specification-card {auditReport ? 'with-audit' : ''} {auditReport && getSpecificationStatus(index, auditReport.data) !== null ? (getSpecificationStatus(index, auditReport.data) === 'skipped' ? 'spec-skipped' : (getSpecificationStatus(index, auditReport.data) ? 'spec-pass' : 'spec-fail')) : ''}">
|
||||
<div
|
||||
class="spec-card-header"
|
||||
@@ -260,19 +267,19 @@
|
||||
<p class="spec-description">{spec["@description"]}</p>
|
||||
{/if}
|
||||
<div class="spec-stats">
|
||||
{#if spec.applicability["@minOccurs"] === 1 && spec.applicability["@maxOccurs"] === 'unbounded'}
|
||||
{#if usage === 'required'}
|
||||
<span class="stat-item">Required</span>
|
||||
{/if}
|
||||
{#if spec.applicability["@minOccurs"] === 0 && spec.applicability["@maxOccurs"] === 'unbounded'}
|
||||
{#if usage === 'optional'}
|
||||
<span class="stat-item">Optional</span>
|
||||
{/if}
|
||||
{#if spec.applicability["@minOccurs"] === 0 && spec.applicability["@maxOccurs"] === 0}
|
||||
{#if usage === 'prohibited'}
|
||||
<span class="stat-item">Prohibited</span>
|
||||
{/if}
|
||||
{#if auditReport}
|
||||
{@const stats = getSpecificationStats(index, auditReport.data)}
|
||||
{@const status = getSpecificationStatus(index, auditReport.data)}
|
||||
{#if stats && spec.applicability["@maxOccurs"] !== 0 && status !== 'skipped'}
|
||||
{#if stats && usage !== 'prohibited' && status !== 'skipped'}
|
||||
<span class="stat-item">Checks: {stats.checksPassed}/{stats.checksTotal}</span>
|
||||
<span class="stat-item">Requirements: {stats.requirementsPassed}/{stats.requirements}</span>
|
||||
{/if}
|
||||
@@ -325,12 +332,13 @@
|
||||
|
||||
{#if auditReport}
|
||||
{@const status = getSpecificationStatus(index, auditReport.data)}
|
||||
{#if ! status && spec.applicability["@maxOccurs"] == 0}
|
||||
{#if status === false && usage === 'prohibited'}
|
||||
{@const specReport = auditReport.data.specifications[index]}
|
||||
{@const applicableEntities = specReport.applicable_entities ?? []}
|
||||
<div class="entity-tables">
|
||||
{#if specReport.applicable_entities && specReport.applicable_entities.length > 0}
|
||||
{#if applicableEntities.length > 0}
|
||||
<div class="entity-table-section fail">
|
||||
<h4>Failed Elements ({specReport.applicable_entities.length})</h4>
|
||||
<h4>Failed Elements ({applicableEntities.length})</h4>
|
||||
<div class="entity-table-container">
|
||||
<Tooltip.Provider>
|
||||
<table class="entity-table">
|
||||
@@ -346,7 +354,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each specReport.applicable_entities.slice(0, 10) as entity}
|
||||
{#each applicableEntities.slice(0, 10) as entity}
|
||||
<tr>
|
||||
<td>{entity.class}</td>
|
||||
<td>{entity.predefined_type || '-'}</td>
|
||||
@@ -402,9 +410,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
{#if specReport.applicable_entities.length > 10}
|
||||
{#if applicableEntities.length > 10}
|
||||
<tr class="more-row">
|
||||
<td colspan="7">... {specReport.applicable_entities.length - 10} more failing elements not shown ...</td>
|
||||
<td colspan="7">... {applicableEntities.length - 10} more failing elements not shown ...</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
<script lang="ts">
|
||||
import Svelecte from 'svelecte';
|
||||
import { getEntityClasses, getMaterialCategories, getClassificationSystems, getDataTypes, getPredefinedTypes, getEntityAttributes, getApplicablePsets } from '$src/modules/api/api.svelte';
|
||||
import {
|
||||
getApplicablePsets,
|
||||
getClassificationSystems,
|
||||
getDataTypes,
|
||||
getEntityAttributes,
|
||||
getEntityClasses,
|
||||
getMaterialCategories,
|
||||
getPredefinedTypes
|
||||
} from '$src/modules/api/api.svelte';
|
||||
import * as IDS from '$src/modules/api/ids.svelte';
|
||||
import type { DocumentState, Facet, FacetValue, IdsDocument, Restriction, RestrictionValue, Specification } from '$src/types/ids';
|
||||
|
||||
@@ -29,16 +37,17 @@
|
||||
autocomplete?: AutocompleteType;
|
||||
isSpecialProp?: boolean;
|
||||
} = $props();
|
||||
|
||||
const isEntityNameField = autocomplete === 'entityName';
|
||||
const isMaterialField = autocomplete === 'material';
|
||||
const isClassificationSystemField = autocomplete === 'classificationSystem';
|
||||
const isPredefinedTypeField = autocomplete === 'predefinedType';
|
||||
const isAttributeNameField = autocomplete === 'attributeName';
|
||||
const isPropertySetField = autocomplete === 'propertySet';
|
||||
const isDataTypeField = autocomplete === 'dataType';
|
||||
|
||||
const baseId = `restriction-${fieldName}-${Math.random().toString(36).slice(2, 8)}`;
|
||||
let isEntityNameField = $derived(autocomplete === 'entityName');
|
||||
let isMaterialField = $derived(autocomplete === 'material');
|
||||
let isClassificationSystemField = $derived(autocomplete === 'classificationSystem');
|
||||
let isPredefinedTypeField = $derived(autocomplete === 'predefinedType');
|
||||
let isAttributeNameField = $derived(autocomplete === 'attributeName');
|
||||
let isPropertySetField = $derived(autocomplete === 'propertySet');
|
||||
let isDataTypeField = $derived(autocomplete === 'dataType');
|
||||
|
||||
const uniqueId = Math.random().toString(36).slice(2, 8);
|
||||
let baseId = $derived(`restriction-${fieldName}-${uniqueId}`);
|
||||
|
||||
// Predefined Types autocompletions
|
||||
let predefinedTypeOptions: string[] = $state([]);
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
? (activeDocument.specifications.specification[documentState.activeSpecification] as Specification)
|
||||
: null
|
||||
);
|
||||
let importableDocuments = $derived(
|
||||
Object.entries(IDS.Module.documents).filter(
|
||||
([docId, doc]) => docId !== IDS.Module.activeDocument && doc.specifications?.specification?.length > 0
|
||||
) as [string, IdsDocument][]
|
||||
);
|
||||
|
||||
async function addNewSpecification() {
|
||||
if (!IDS.Module.activeDocument) return;
|
||||
@@ -153,8 +158,7 @@
|
||||
Import from IDS
|
||||
</DropdownMenu.SubTrigger>
|
||||
<DropdownMenu.SubContent class="w-64 max-h-64 overflow-y-auto">
|
||||
{#each Object.entries(IDS.Module.documents) as [docId, doc]}
|
||||
{#if docId !== IDS.Module.activeDocument && doc.specifications?.specification?.length > 0}
|
||||
{#each importableDocuments as [docId, doc], docIndex}
|
||||
<DropdownMenu.Label class="font-medium text-xs text-muted-foreground px-2 py-1 truncate">
|
||||
{doc.info?.title || 'Untitled Document'}
|
||||
</DropdownMenu.Label>
|
||||
@@ -169,12 +173,11 @@
|
||||
</span>
|
||||
</DropdownMenu.Item>
|
||||
{/each}
|
||||
{#if Object.entries(IDS.Module.documents).filter(([id, d]) => id !== IDS.Module.activeDocument && d.specifications?.specification?.length > 0).indexOf([docId, doc]) < Object.entries(IDS.Module.documents).filter(([id, d]) => id !== IDS.Module.activeDocument && d.specifications?.specification?.length > 0).length - 1}
|
||||
{#if docIndex < importableDocuments.length - 1}
|
||||
<DropdownMenu.Separator />
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
{#if Object.entries(IDS.Module.documents).filter(([docId, doc]) => docId !== IDS.Module.activeDocument && doc.specifications?.specification?.length > 0).length === 0}
|
||||
{#if importableDocuments.length === 0}
|
||||
<DropdownMenu.Item disabled>
|
||||
<span class="text-sm">No specifications available to import</span>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
@@ -44,6 +44,7 @@ export type AuditSpecification = {
|
||||
description: string;
|
||||
instructions: string;
|
||||
status: boolean;
|
||||
is_skipped?: boolean;
|
||||
is_ifc_version: boolean;
|
||||
total_applicable: number;
|
||||
total_applicable_pass: number;
|
||||
@@ -55,6 +56,7 @@ export type AuditSpecification = {
|
||||
percent_checks_pass: ResultsPercent;
|
||||
cardinality: string;
|
||||
applicability: string[];
|
||||
applicable_entities?: AuditReportEntity[];
|
||||
requirements: AuditRequirement[];
|
||||
total_requirements?: number;
|
||||
total_requirements_pass?: number;
|
||||
|
||||
Reference in New Issue
Block a user