@open-mercato/core 0.6.6-develop.6290.1.4bb5a8ba3f → 0.6.6-develop.6299.1.29224e2d86
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.
- package/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +8 -0
- package/dist/generated/entities/module_config/index.js +4 -0
- package/dist/generated/entities/module_config/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +2 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/auth/lib/setup-app.js +1 -1
- package/dist/modules/auth/lib/setup-app.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductComplianceSection.js +235 -62
- package/dist/modules/catalog/components/products/ProductComplianceSection.js.map +2 -2
- package/dist/modules/configs/components/CachePanel.js +2 -1
- package/dist/modules/configs/components/CachePanel.js.map +2 -2
- package/dist/modules/configs/components/SystemStatusPanel.js +10 -12
- package/dist/modules/configs/components/SystemStatusPanel.js.map +2 -2
- package/dist/modules/configs/data/entities.js +15 -1
- package/dist/modules/configs/data/entities.js.map +2 -2
- package/dist/modules/configs/lib/module-config-service.js +52 -19
- package/dist/modules/configs/lib/module-config-service.js.map +3 -3
- package/dist/modules/configs/migrations/Migration20260617150000.js +21 -0
- package/dist/modules/configs/migrations/Migration20260617150000.js.map +7 -0
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js +47 -1
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js.map +2 -2
- package/generated/entities/module_config/index.ts +2 -0
- package/generated/entity-fields-registry.ts +2 -0
- package/package.json +7 -7
- package/src/modules/auth/lib/setup-app.ts +1 -1
- package/src/modules/catalog/components/products/ProductComplianceSection.tsx +138 -27
- package/src/modules/configs/components/CachePanel.tsx +2 -3
- package/src/modules/configs/components/SystemStatusPanel.tsx +12 -19
- package/src/modules/configs/data/entities.ts +17 -1
- package/src/modules/configs/lib/module-config-service.ts +83 -24
- package/src/modules/configs/migrations/.snapshot-open-mercato.json +41 -4
- package/src/modules/configs/migrations/.snapshot-openmercato.json +41 -4
- package/src/modules/configs/migrations/Migration20260617150000.ts +21 -0
- package/src/modules/customers/api/activities/route.ts +6 -0
- package/src/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.ts +54 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/catalog/components/products/ProductComplianceSection.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { Checkbox } from \"@open-mercato/ui/primitives/checkbox\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport { Label } from \"@open-mercato/ui/primitives/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@open-mercato/ui/primitives/select\";\nimport { Textarea } from \"@open-mercato/ui/primitives/textarea\";\nimport {\n CATALOG_EXCISE_CATEGORIES,\n CATALOG_GTU_CODES,\n CATALOG_HAZMAT_PACKING_GROUPS,\n} from \"../../data/types\";\nimport type { ProductFormValues } from \"./productForm\";\n\nconst NONE_OPTION = \"none\";\n\ntype ProductComplianceSectionProps = {\n values: ProductFormValues;\n errors: Record<string, string>;\n setValue: (id: string, value: unknown) => void;\n embedded?: boolean;\n};\n\nfunction FieldError({ message }: { message?: string }) {\n if (!message) return null;\n return <p className=\"text-xs text-destructive\">{message}</p>;\n}\n\nexport function ProductComplianceSection({\n values,\n errors,\n setValue,\n embedded = false,\n}: ProductComplianceSectionProps) {\n const t = useT();\n const gtuCodes = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n\n const toggleGtuCode = React.useCallback(\n (code: string, checked: boolean) => {\n const current = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n const next = checked\n ? Array.from(new Set([...current, code])).sort()\n : current.filter((entry) => entry !== code);\n setValue(\"gtuCodes\", next);\n },\n [setValue, values.gtuCodes],\n );\n\n return (\n <div\n className={\n embedded ? \"space-y-6\" : \"space-y-6 rounded-lg border bg-card p-4\"\n }\n >\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.codes.title\", \"Compliance codes (PL/EU)\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.codes.description\",\n \"Classification codes used by KSeF/JPK invoices, customs declarations, and marketplace feeds.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-country\">\n {t(\"catalog.products.compliance.fields.countryOfOrigin\", \"Country of origin (ISO code)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-country\"\n value={values.countryOfOriginCode ?? \"\"}\n maxLength={2}\n placeholder={t(\"catalog.products.compliance.placeholders.countryOfOrigin\", \"PL\")}\n onChange={(event) =>\n setValue(\"countryOfOriginCode\", event.target.value.toUpperCase())\n }\n />\n <FieldError message={errors.countryOfOriginCode} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-tax-classification\">\n {t(\"catalog.products.compliance.fields.taxClassification\", \"Tax classification code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-tax-classification\"\n value={values.taxClassificationCode ?? \"\"}\n onChange={(event) => setValue(\"taxClassificationCode\", event.target.value)}\n />\n <FieldError message={errors.taxClassificationCode} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-pkwiu\">\n {t(\"catalog.products.compliance.fields.pkwiu\", \"PKWiU code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-pkwiu\"\n value={values.pkwiuCode ?? \"\"}\n onChange={(event) => setValue(\"pkwiuCode\", event.target.value)}\n />\n <FieldError message={errors.pkwiuCode} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-cn\">\n {t(\"catalog.products.compliance.fields.cn\", \"CN code (Combined Nomenclature)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-cn\"\n value={values.cnCode ?? \"\"}\n onChange={(event) => setValue(\"cnCode\", event.target.value)}\n />\n <FieldError message={errors.cnCode} />\n </div>\n <div className=\"space-y-2 md:col-span-2\">\n <Label htmlFor=\"catalog-product-compliance-hs\">\n {t(\"catalog.products.compliance.fields.hs\", \"HS code (customs tariff)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hs\"\n value={values.hsCode ?? \"\"}\n onChange={(event) => setValue(\"hsCode\", event.target.value)}\n />\n <FieldError message={errors.hsCode} />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>{t(\"catalog.products.compliance.fields.gtuCodes\", \"GTU codes (JPK_V7)\")}</Label>\n <div className=\"grid gap-2 sm:grid-cols-3 md:grid-cols-4\">\n {CATALOG_GTU_CODES.map((code) => (\n <label\n key={code}\n className=\"flex items-center gap-2 text-sm\"\n htmlFor={`catalog-product-compliance-gtu-${code}`}\n >\n <Checkbox\n id={`catalog-product-compliance-gtu-${code}`}\n checked={gtuCodes.includes(code)}\n onCheckedChange={(checked) => toggleGtuCode(code, checked === true)}\n />\n {code.replace(\"_\", \" \")}\n </label>\n ))}\n </div>\n <FieldError message={errors.gtuCodes} />\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.safety.title\", \"Restrictions & safety\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.safety.description\",\n \"Age, excise, and dangerous-goods attributes enforced by storefront, POS, and carriers.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-age-min\">\n {t(\"catalog.products.compliance.fields.ageMin\", \"Minimum buyer age\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-age-min\"\n type=\"number\"\n min={0}\n max={120}\n value={values.ageMin ?? \"\"}\n onChange={(event) => setValue(\"ageMin\", event.target.value)}\n />\n <FieldError message={errors.ageMin} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-excise-category\">\n {t(\"catalog.products.compliance.fields.exciseCategory\", \"Excise category\")}\n </Label>\n <Select\n value={values.exciseCategory ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"exciseCategory\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger id=\"catalog-product-compliance-excise-category\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_EXCISE_CATEGORIES.map((category) => (\n <SelectItem key={category} value={category}>\n {t(`catalog.products.compliance.exciseCategories.${category}`, category)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError message={errors.exciseCategory} />\n </div>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-excise\"\n >\n <Checkbox\n id=\"catalog-product-compliance-excise\"\n checked={values.isExciseGood === true}\n onCheckedChange={(checked) => setValue(\"isExciseGood\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isExciseGood\", \"Excise good\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-prescription\"\n >\n <Checkbox\n id=\"catalog-product-compliance-prescription\"\n checked={values.requiresPrescription === true}\n onCheckedChange={(checked) => setValue(\"requiresPrescription\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresPrescription\", \"Requires prescription\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-lithium\"\n >\n <Checkbox\n id=\"catalog-product-compliance-lithium\"\n checked={values.containsLithiumBattery === true}\n onCheckedChange={(checked) => setValue(\"containsLithiumBattery\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.containsLithiumBattery\", \"Contains lithium battery\")}\n </label>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-hazmat-class\">\n {t(\"catalog.products.compliance.fields.hazmatClass\", \"Hazmat class (ADR)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hazmat-class\"\n value={values.hazmatClass ?? \"\"}\n onChange={(event) => setValue(\"hazmatClass\", event.target.value)}\n />\n <FieldError message={errors.hazmatClass} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-un-number\">\n {t(\"catalog.products.compliance.fields.unNumber\", \"UN number\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-un-number\"\n placeholder={t(\"catalog.products.compliance.placeholders.unNumber\", \"UN1234\")}\n value={values.unNumber ?? \"\"}\n onChange={(event) => setValue(\"unNumber\", event.target.value)}\n />\n <FieldError message={errors.unNumber} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-packing-group\">\n {t(\"catalog.products.compliance.fields.hazmatPackingGroup\", \"Packing group\")}\n </Label>\n <Select\n value={values.hazmatPackingGroup ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"hazmatPackingGroup\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger id=\"catalog-product-compliance-packing-group\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_HAZMAT_PACKING_GROUPS.map((group) => (\n <SelectItem key={group} value={group}>\n {group}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError message={errors.hazmatPackingGroup} />\n </div>\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.logistics.title\", \"Availability & lifecycle\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.logistics.description\",\n \"Launch, end-of-life, and selling windows plus shipping requirements.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-launch-at\">\n {t(\"catalog.products.compliance.fields.launchAt\", \"Launch date\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-launch-at\"\n type=\"date\"\n value={values.launchAt ?? \"\"}\n onChange={(event) => setValue(\"launchAt\", event.target.value)}\n />\n <FieldError message={errors.launchAt} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-eol-at\">\n {t(\"catalog.products.compliance.fields.endOfLifeAt\", \"End of life\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-eol-at\"\n type=\"date\"\n value={values.endOfLifeAt ?? \"\"}\n onChange={(event) => setValue(\"endOfLifeAt\", event.target.value)}\n />\n <FieldError message={errors.endOfLifeAt} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-from\">\n {t(\"catalog.products.compliance.fields.availableFrom\", \"Available from\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-from\"\n type=\"date\"\n value={values.availableFrom ?? \"\"}\n onChange={(event) => setValue(\"availableFrom\", event.target.value)}\n />\n <FieldError message={errors.availableFrom} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-until\">\n {t(\"catalog.products.compliance.fields.availableUntil\", \"Available until\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-until\"\n type=\"date\"\n value={values.availableUntil ?? \"\"}\n onChange={(event) => setValue(\"availableUntil\", event.target.value)}\n />\n <FieldError message={errors.availableUntil} />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-requires-shipping\"\n >\n <Checkbox\n id=\"catalog-product-compliance-requires-shipping\"\n checked={values.requiresShipping !== false}\n onCheckedChange={(checked) => setValue(\"requiresShipping\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresShipping\", \"Requires shipping\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.commercial.title\", \"Commercial terms\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.commercial.description\",\n \"Order quantity constraints and quote-only selling for B2B.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-min-qty\">\n {t(\"catalog.products.compliance.fields.minOrderQty\", \"Minimum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-min-qty\"\n type=\"number\"\n min={1}\n value={values.minOrderQty ?? \"\"}\n onChange={(event) => setValue(\"minOrderQty\", event.target.value)}\n />\n <FieldError message={errors.minOrderQty} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-max-qty\">\n {t(\"catalog.products.compliance.fields.maxOrderQty\", \"Maximum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-max-qty\"\n type=\"number\"\n min={1}\n value={values.maxOrderQty ?? \"\"}\n onChange={(event) => setValue(\"maxOrderQty\", event.target.value)}\n />\n <FieldError message={errors.maxOrderQty} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-qty-increment\">\n {t(\"catalog.products.compliance.fields.orderQtyIncrement\", \"Quantity increment\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-qty-increment\"\n type=\"number\"\n min={1}\n value={values.orderQtyIncrement ?? \"\"}\n onChange={(event) => setValue(\"orderQtyIncrement\", event.target.value)}\n />\n <FieldError message={errors.orderQtyIncrement} />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-quote-only\"\n >\n <Checkbox\n id=\"catalog-product-compliance-quote-only\"\n checked={values.isQuoteOnly === true}\n onCheckedChange={(checked) => setValue(\"isQuoteOnly\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isQuoteOnly\", \"Quote only (price on request)\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.seo.title\", \"SEO\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.seo.description\",\n \"Storefront metadata. Title and description are translatable per locale.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-title\">\n {t(\"catalog.products.compliance.fields.seoTitle\", \"SEO title\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-seo-title\"\n maxLength={255}\n value={values.seoTitle ?? \"\"}\n onChange={(event) => setValue(\"seoTitle\", event.target.value)}\n />\n <FieldError message={errors.seoTitle} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-description\">\n {t(\"catalog.products.compliance.fields.seoDescription\", \"SEO description\")}\n </Label>\n <Textarea\n id=\"catalog-product-compliance-seo-description\"\n rows={3}\n maxLength={1000}\n value={values.seoDescription ?? \"\"}\n onChange={(event) => setValue(\"seoDescription\", event.target.value)}\n />\n <FieldError message={errors.seoDescription} />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-canonical-url\">\n {t(\"catalog.products.compliance.fields.canonicalUrl\", \"Canonical URL\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-canonical-url\"\n type=\"url\"\n maxLength={500}\n placeholder=\"https://\"\n value={values.canonicalUrl ?? \"\"}\n onChange={(event) => setValue(\"canonicalUrl\", event.target.value)}\n />\n <FieldError message={errors.canonicalUrl} />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { Checkbox } from \"@open-mercato/ui/primitives/checkbox\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport { Label } from \"@open-mercato/ui/primitives/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@open-mercato/ui/primitives/select\";\nimport { Textarea } from \"@open-mercato/ui/primitives/textarea\";\nimport {\n CATALOG_EXCISE_CATEGORIES,\n CATALOG_GTU_CODES,\n CATALOG_HAZMAT_PACKING_GROUPS,\n} from \"../../data/types\";\nimport type { ProductFormValues } from \"./productForm\";\n\nconst NONE_OPTION = \"none\";\n\ntype ProductComplianceSectionProps = {\n values: ProductFormValues;\n errors: Record<string, string>;\n setValue: (id: string, value: unknown) => void;\n embedded?: boolean;\n};\n\nfunction fieldErrorId(inputId: string) {\n return `${inputId}-error`;\n}\n\nfunction describedByError(\n inputId: string,\n message?: string,\n): { \"aria-invalid\"?: true; \"aria-describedby\"?: string } {\n return message\n ? { \"aria-invalid\": true, \"aria-describedby\": fieldErrorId(inputId) }\n : {};\n}\n\nfunction FieldError({ id, message }: { id: string; message?: string }) {\n if (!message) return null;\n return (\n <p id={id} className=\"text-xs text-destructive\">\n {message}\n </p>\n );\n}\n\nexport function ProductComplianceSection({\n values,\n errors,\n setValue,\n embedded = false,\n}: ProductComplianceSectionProps) {\n const t = useT();\n const gtuCodes = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n\n const toggleGtuCode = React.useCallback(\n (code: string, checked: boolean) => {\n const current = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n const next = checked\n ? Array.from(new Set([...current, code])).sort()\n : current.filter((entry) => entry !== code);\n setValue(\"gtuCodes\", next);\n },\n [setValue, values.gtuCodes],\n );\n\n return (\n <div\n className={\n embedded ? \"space-y-6\" : \"space-y-6 rounded-lg border bg-card p-4\"\n }\n >\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.codes.title\", \"Compliance codes (PL/EU)\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.codes.description\",\n \"Classification codes used by KSeF/JPK invoices, customs declarations, and marketplace feeds.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-country\">\n {t(\"catalog.products.compliance.fields.countryOfOrigin\", \"Country of origin (ISO code)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-country\"\n value={values.countryOfOriginCode ?? \"\"}\n maxLength={2}\n placeholder={t(\"catalog.products.compliance.placeholders.countryOfOrigin\", \"PL\")}\n onChange={(event) =>\n setValue(\"countryOfOriginCode\", event.target.value.toUpperCase())\n }\n {...describedByError(\"catalog-product-compliance-country\", errors.countryOfOriginCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-country\")}\n message={errors.countryOfOriginCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-tax-classification\">\n {t(\"catalog.products.compliance.fields.taxClassification\", \"Tax classification code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-tax-classification\"\n value={values.taxClassificationCode ?? \"\"}\n onChange={(event) => setValue(\"taxClassificationCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-tax-classification\", errors.taxClassificationCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-tax-classification\")}\n message={errors.taxClassificationCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-pkwiu\">\n {t(\"catalog.products.compliance.fields.pkwiu\", \"PKWiU code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-pkwiu\"\n value={values.pkwiuCode ?? \"\"}\n onChange={(event) => setValue(\"pkwiuCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-pkwiu\", errors.pkwiuCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-pkwiu\")}\n message={errors.pkwiuCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-cn\">\n {t(\"catalog.products.compliance.fields.cn\", \"CN code (Combined Nomenclature)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-cn\"\n value={values.cnCode ?? \"\"}\n onChange={(event) => setValue(\"cnCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-cn\", errors.cnCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-cn\")}\n message={errors.cnCode}\n />\n </div>\n <div className=\"space-y-2 md:col-span-2\">\n <Label htmlFor=\"catalog-product-compliance-hs\">\n {t(\"catalog.products.compliance.fields.hs\", \"HS code (customs tariff)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hs\"\n value={values.hsCode ?? \"\"}\n onChange={(event) => setValue(\"hsCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-hs\", errors.hsCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-hs\")}\n message={errors.hsCode}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label id=\"catalog-product-compliance-gtu-label\">\n {t(\"catalog.products.compliance.fields.gtuCodes\", \"GTU codes (JPK_V7)\")}\n </Label>\n <div\n role=\"group\"\n aria-labelledby=\"catalog-product-compliance-gtu-label\"\n className=\"grid gap-2 sm:grid-cols-3 md:grid-cols-4\"\n {...describedByError(\"catalog-product-compliance-gtu\", errors.gtuCodes)}\n >\n {CATALOG_GTU_CODES.map((code) => (\n <label\n key={code}\n className=\"flex items-center gap-2 text-sm\"\n htmlFor={`catalog-product-compliance-gtu-${code}`}\n >\n <Checkbox\n id={`catalog-product-compliance-gtu-${code}`}\n checked={gtuCodes.includes(code)}\n onCheckedChange={(checked) => toggleGtuCode(code, checked === true)}\n />\n {code.replace(\"_\", \" \")}\n </label>\n ))}\n </div>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-gtu\")}\n message={errors.gtuCodes}\n />\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.safety.title\", \"Restrictions & safety\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.safety.description\",\n \"Age, excise, and dangerous-goods attributes enforced by storefront, POS, and carriers.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-age-min\">\n {t(\"catalog.products.compliance.fields.ageMin\", \"Minimum buyer age\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-age-min\"\n type=\"number\"\n min={0}\n max={120}\n value={values.ageMin ?? \"\"}\n onChange={(event) => setValue(\"ageMin\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-age-min\", errors.ageMin)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-age-min\")}\n message={errors.ageMin}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-excise-category\">\n {t(\"catalog.products.compliance.fields.exciseCategory\", \"Excise category\")}\n </Label>\n <Select\n value={values.exciseCategory ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"exciseCategory\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger\n id=\"catalog-product-compliance-excise-category\"\n {...describedByError(\"catalog-product-compliance-excise-category\", errors.exciseCategory)}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_EXCISE_CATEGORIES.map((category) => (\n <SelectItem key={category} value={category}>\n {t(`catalog.products.compliance.exciseCategories.${category}`, category)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-excise-category\")}\n message={errors.exciseCategory}\n />\n </div>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-excise\"\n >\n <Checkbox\n id=\"catalog-product-compliance-excise\"\n checked={values.isExciseGood === true}\n onCheckedChange={(checked) => setValue(\"isExciseGood\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isExciseGood\", \"Excise good\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-prescription\"\n >\n <Checkbox\n id=\"catalog-product-compliance-prescription\"\n checked={values.requiresPrescription === true}\n onCheckedChange={(checked) => setValue(\"requiresPrescription\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresPrescription\", \"Requires prescription\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-lithium\"\n >\n <Checkbox\n id=\"catalog-product-compliance-lithium\"\n checked={values.containsLithiumBattery === true}\n onCheckedChange={(checked) => setValue(\"containsLithiumBattery\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.containsLithiumBattery\", \"Contains lithium battery\")}\n </label>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-hazmat-class\">\n {t(\"catalog.products.compliance.fields.hazmatClass\", \"Hazmat class (ADR)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hazmat-class\"\n value={values.hazmatClass ?? \"\"}\n onChange={(event) => setValue(\"hazmatClass\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-hazmat-class\", errors.hazmatClass)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-hazmat-class\")}\n message={errors.hazmatClass}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-un-number\">\n {t(\"catalog.products.compliance.fields.unNumber\", \"UN number\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-un-number\"\n placeholder={t(\"catalog.products.compliance.placeholders.unNumber\", \"UN1234\")}\n value={values.unNumber ?? \"\"}\n onChange={(event) => setValue(\"unNumber\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-un-number\", errors.unNumber)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-un-number\")}\n message={errors.unNumber}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-packing-group\">\n {t(\"catalog.products.compliance.fields.hazmatPackingGroup\", \"Packing group\")}\n </Label>\n <Select\n value={values.hazmatPackingGroup ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"hazmatPackingGroup\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger\n id=\"catalog-product-compliance-packing-group\"\n {...describedByError(\"catalog-product-compliance-packing-group\", errors.hazmatPackingGroup)}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_HAZMAT_PACKING_GROUPS.map((group) => (\n <SelectItem key={group} value={group}>\n {group}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-packing-group\")}\n message={errors.hazmatPackingGroup}\n />\n </div>\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.logistics.title\", \"Availability & lifecycle\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.logistics.description\",\n \"Launch, end-of-life, and selling windows plus shipping requirements.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-launch-at\">\n {t(\"catalog.products.compliance.fields.launchAt\", \"Launch date\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-launch-at\"\n type=\"date\"\n value={values.launchAt ?? \"\"}\n onChange={(event) => setValue(\"launchAt\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-launch-at\", errors.launchAt)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-launch-at\")}\n message={errors.launchAt}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-eol-at\">\n {t(\"catalog.products.compliance.fields.endOfLifeAt\", \"End of life\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-eol-at\"\n type=\"date\"\n value={values.endOfLifeAt ?? \"\"}\n onChange={(event) => setValue(\"endOfLifeAt\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-eol-at\", errors.endOfLifeAt)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-eol-at\")}\n message={errors.endOfLifeAt}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-from\">\n {t(\"catalog.products.compliance.fields.availableFrom\", \"Available from\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-from\"\n type=\"date\"\n value={values.availableFrom ?? \"\"}\n onChange={(event) => setValue(\"availableFrom\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-available-from\", errors.availableFrom)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-available-from\")}\n message={errors.availableFrom}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-until\">\n {t(\"catalog.products.compliance.fields.availableUntil\", \"Available until\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-until\"\n type=\"date\"\n value={values.availableUntil ?? \"\"}\n onChange={(event) => setValue(\"availableUntil\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-available-until\", errors.availableUntil)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-available-until\")}\n message={errors.availableUntil}\n />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-requires-shipping\"\n >\n <Checkbox\n id=\"catalog-product-compliance-requires-shipping\"\n checked={values.requiresShipping !== false}\n onCheckedChange={(checked) => setValue(\"requiresShipping\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresShipping\", \"Requires shipping\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.commercial.title\", \"Commercial terms\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.commercial.description\",\n \"Order quantity constraints and quote-only selling for B2B.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-min-qty\">\n {t(\"catalog.products.compliance.fields.minOrderQty\", \"Minimum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-min-qty\"\n type=\"number\"\n min={1}\n value={values.minOrderQty ?? \"\"}\n onChange={(event) => setValue(\"minOrderQty\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-min-qty\", errors.minOrderQty)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-min-qty\")}\n message={errors.minOrderQty}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-max-qty\">\n {t(\"catalog.products.compliance.fields.maxOrderQty\", \"Maximum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-max-qty\"\n type=\"number\"\n min={1}\n value={values.maxOrderQty ?? \"\"}\n onChange={(event) => setValue(\"maxOrderQty\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-max-qty\", errors.maxOrderQty)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-max-qty\")}\n message={errors.maxOrderQty}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-qty-increment\">\n {t(\"catalog.products.compliance.fields.orderQtyIncrement\", \"Quantity increment\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-qty-increment\"\n type=\"number\"\n min={1}\n value={values.orderQtyIncrement ?? \"\"}\n onChange={(event) => setValue(\"orderQtyIncrement\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-qty-increment\", errors.orderQtyIncrement)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-qty-increment\")}\n message={errors.orderQtyIncrement}\n />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-quote-only\"\n >\n <Checkbox\n id=\"catalog-product-compliance-quote-only\"\n checked={values.isQuoteOnly === true}\n onCheckedChange={(checked) => setValue(\"isQuoteOnly\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isQuoteOnly\", \"Quote only (price on request)\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.seo.title\", \"SEO\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.seo.description\",\n \"Storefront metadata. Title and description are translatable per locale.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-title\">\n {t(\"catalog.products.compliance.fields.seoTitle\", \"SEO title\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-seo-title\"\n maxLength={255}\n value={values.seoTitle ?? \"\"}\n onChange={(event) => setValue(\"seoTitle\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-seo-title\", errors.seoTitle)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-seo-title\")}\n message={errors.seoTitle}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-description\">\n {t(\"catalog.products.compliance.fields.seoDescription\", \"SEO description\")}\n </Label>\n <Textarea\n id=\"catalog-product-compliance-seo-description\"\n rows={3}\n maxLength={1000}\n value={values.seoDescription ?? \"\"}\n onChange={(event) => setValue(\"seoDescription\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-seo-description\", errors.seoDescription)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-seo-description\")}\n message={errors.seoDescription}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-canonical-url\">\n {t(\"catalog.products.compliance.fields.canonicalUrl\", \"Canonical URL\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-canonical-url\"\n type=\"url\"\n maxLength={500}\n placeholder=\"https://\"\n value={values.canonicalUrl ?? \"\"}\n onChange={(event) => setValue(\"canonicalUrl\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-canonical-url\", errors.canonicalUrl)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-canonical-url\")}\n message={errors.canonicalUrl}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,6 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { Spinner } from "@open-mercato/ui/primitives/spinner";
|
|
5
5
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
6
6
|
import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
7
|
+
import { ErrorMessage } from "@open-mercato/ui/backend/detail";
|
|
7
8
|
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
|
|
8
9
|
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
9
10
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
@@ -194,7 +195,7 @@ function CachePanel() {
|
|
|
194
195
|
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: t("configs.cache.title", "Cache overview") }),
|
|
195
196
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("configs.cache.description", "Inspect cached responses and clear segments when necessary.") })
|
|
196
197
|
] }),
|
|
197
|
-
/* @__PURE__ */ jsx(
|
|
198
|
+
/* @__PURE__ */ jsx(ErrorMessage, { label: state.error }),
|
|
198
199
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: /* @__PURE__ */ jsx(Button, { variant: "outline", type: "button", onClick: handleRefresh, children: t("configs.cache.retry", "Retry") }) })
|
|
199
200
|
] });
|
|
200
201
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/configs/components/CachePanel.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { hasFeature } from '@open-mercato/shared/security/features'\n\nconst MANAGE_FEATURE = 'configs.cache.manage'\n\nconst API_PATH = '/api/configs/cache'\nconst CACHE_MUTATION_CONTEXT_ID = 'configs-cache-panel'\n\ntype CrudCacheSegment = {\n segment: string\n resource: string | null\n method: string | null\n path: string | null\n keyCount: number\n}\n\ntype CrudCacheStats = {\n generatedAt: string\n totalKeys: number\n segments: CrudCacheSegment[]\n}\n\ntype FetchState = {\n loading: boolean\n error: string | null\n stats: CrudCacheStats | null\n}\n\nexport function CachePanel() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [state, setState] = React.useState<FetchState>({ loading: true, error: null, stats: null })\n const [canManage, setCanManage] = React.useState(false)\n const [checkingFeature, setCheckingFeature] = React.useState(true)\n const [purgingAll, setPurgingAll] = React.useState(false)\n const [segmentPurges, setSegmentPurges] = React.useState<Record<string, boolean>>({})\n\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: CACHE_MUTATION_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const cacheMutationContext = React.useMemo(\n () => ({\n formId: CACHE_MUTATION_CONTEXT_ID,\n resourceKind: 'configs.cache',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n\n const loadStats = React.useCallback(async () => {\n setState((current) => ({ ...current, loading: true, error: null }))\n try {\n const stats = await readApiResultOrThrow<CrudCacheStats>(API_PATH, undefined, {\n errorMessage: t('configs.cache.loadError', 'Failed to load cache statistics.'),\n })\n setState({ loading: false, error: null, stats })\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.cache.loadError', 'Failed to load cache statistics.')\n setState({ loading: false, error: message, stats: null })\n }\n }, [t])\n\n React.useEffect(() => {\n loadStats().catch(() => {})\n }, [loadStats])\n\n React.useEffect(() => {\n let cancelled = false\n async function checkManageFeature() {\n try {\n const payload = await readApiResultOrThrow<{ ok?: boolean; granted?: unknown }>(\n '/api/auth/feature-check',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: [MANAGE_FEATURE] }),\n },\n {\n errorMessage: t('configs.cache.loadError', 'Failed to load cache statistics.'),\n allowNullResult: true,\n },\n )\n if (cancelled) return\n const granted = Array.isArray(payload?.granted)\n ? (payload.granted as unknown[]).filter((feature) => typeof feature === 'string') as string[]\n : []\n const canManageFeature = payload?.ok === true || hasFeature(granted, MANAGE_FEATURE)\n setCanManage(canManageFeature)\n } catch {\n if (!cancelled) setCanManage(false)\n } finally {\n if (!cancelled) setCheckingFeature(false)\n }\n }\n checkManageFeature().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [t])\n\n const handleRefresh = React.useCallback(() => {\n loadStats().catch(() => {})\n }, [loadStats])\n\n const handlePurgeAll = React.useCallback(async () => {\n if (!canManage || purgingAll) return\n const confirmed = await confirm({\n title: t('configs.cache.purgeAllConfirm', 'Purge all cached entries for this tenant?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPurgingAll(true)\n try {\n const payload = await runMutation({\n operation: () =>\n readApiResultOrThrow<{ stats?: CrudCacheStats }>(\n API_PATH,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ action: 'purgeAll' }),\n },\n {\n errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),\n allowNullResult: true,\n },\n ),\n context: cacheMutationContext,\n mutationPayload: { action: 'purgeAll' },\n })\n const stats = payload?.stats\n if (stats) {\n setState({ loading: false, error: null, stats })\n } else {\n handleRefresh()\n }\n flash(t('configs.cache.purgeAllSuccess', 'Cache cleared.'), 'success')\n setSegmentPurges({})\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.cache.purgeError', 'Failed to purge cache segment.')\n flash(message, 'error')\n } finally {\n setPurgingAll(false)\n }\n }, [canManage, confirm, purgingAll, t, handleRefresh, runMutation, cacheMutationContext]);\n\n\n const handlePurgeSegment = React.useCallback(async (segment: string) => {\n if (!canManage || segmentPurges[segment]) return\n const confirmed = await confirm({\n title: t('configs.cache.purgeSegmentConfirm', 'Purge cached entries for this segment?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setSegmentPurges((prev) => ({ ...prev, [segment]: true }))\n try {\n const payload = await runMutation({\n operation: () =>\n readApiResultOrThrow<{ stats?: CrudCacheStats; deleted?: number }>(\n API_PATH,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ action: 'purgeSegment', segment }),\n },\n {\n errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),\n allowNullResult: true,\n },\n ),\n context: cacheMutationContext,\n mutationPayload: { action: 'purgeSegment', segment },\n })\n const stats = payload?.stats\n if (stats) {\n setState({ loading: false, error: null, stats })\n } else {\n handleRefresh()\n }\n const deleted = typeof payload?.deleted === 'number' ? payload.deleted : 0\n flash(\n t('configs.cache.purgeSegmentSuccess', {\n segment,\n count: deleted,\n }),\n 'success'\n )\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.cache.purgeError', 'Failed to purge cache segment.')\n flash(message, 'error')\n } finally {\n setSegmentPurges((prev) => {\n const next = { ...prev }\n delete next[segment]\n return next\n })\n }\n }, [canManage, confirm, segmentPurges, t, handleRefresh, runMutation, cacheMutationContext]);\n\n if (state.loading) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n {ConfirmDialogElement}\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.cache.title', 'Cache overview')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}\n </p>\n </header>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n {t('configs.cache.loading', 'Loading cache statistics\u2026')}\n </div>\n </section>\n )\n }\n\n if (state.error) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n {ConfirmDialogElement}\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.cache.title', 'Cache overview')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}\n </p>\n </header>\n <div className=\"rounded border border-red-200 bg-red-50 p-3 text-sm text-red-700\">\n {state.error}\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button variant=\"outline\" type=\"button\" onClick={handleRefresh}>\n {t('configs.cache.retry', 'Retry')}\n </Button>\n </div>\n </section>\n )\n }\n\n const stats = state.stats\n const canShowActions = !checkingFeature && canManage\n\n return (\n <section className=\"space-y-6 rounded-lg border bg-background p-6\">\n <header className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.cache.title', 'Cache overview')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}\n </p>\n {stats ? (\n <>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.cache.generatedAt',\n 'Stats generated {{timestamp}}',\n { timestamp: new Date(stats.generatedAt).toLocaleString() }\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.cache.totalEntries',\n '{{count}} cached entries',\n { count: stats.totalKeys }\n )}\n </p>\n </>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" type=\"button\" onClick={handleRefresh}>\n {t('configs.cache.refresh', 'Refresh')}\n </Button>\n {canShowActions ? (\n <Button variant=\"destructive\" type=\"button\" disabled={purgingAll} onClick={() => { void handlePurgeAll() }}>\n {purgingAll\n ? t('configs.cache.purgeAllLoading', 'Purging\u2026')\n : t('configs.cache.purgeAll', 'Purge all cache')}\n </Button>\n ) : null}\n </div>\n </header>\n <div className=\"space-y-4 rounded-lg border bg-card p-4\">\n {stats && stats.segments.length ? (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[560px] text-sm\">\n <thead>\n <tr className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.segment', 'Segment')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.path', 'Path')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.method', 'Method')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.count', 'Cached keys')}\n </th>\n {canShowActions ? (\n <th className=\"px-3 py-2 text-right\">\n {t('configs.cache.table.actions', 'Actions')}\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody>\n {stats.segments.map((segment) => {\n const isPurging = !!segmentPurges[segment.segment]\n return (\n <tr key={segment.segment} className=\"border-t\">\n <td className=\"px-3 py-2 align-top font-medium\">\n <div className=\"flex flex-col\">\n <span>{segment.segment}</span>\n {segment.resource ? (\n <span className=\"text-xs text-muted-foreground\">{segment.resource}</span>\n ) : null}\n </div>\n </td>\n <td className=\"px-3 py-2 align-top\">\n <code className=\"text-xs text-muted-foreground\">\n {segment.path ?? t('configs.cache.table.pathUnknown', 'n/a')}\n </code>\n </td>\n <td className=\"px-3 py-2 align-top\">\n <span className=\"text-xs uppercase text-muted-foreground\">\n {segment.method ?? 'GET'}\n </span>\n </td>\n <td className=\"px-3 py-2 align-top\">\n {t('configs.cache.table.countValue', '{{count}} keys', { count: segment.keyCount })}\n </td>\n {canShowActions ? (\n <td className=\"px-3 py-2 align-top text-right\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n disabled={isPurging}\n onClick={() => { void handlePurgeSegment(segment.segment) }}\n >\n {isPurging\n ? t('configs.cache.purgeSegmentLoading', 'Purging\u2026')\n : t('configs.cache.purgeSegment', 'Purge segment')}\n </Button>\n </td>\n ) : null}\n </tr>\n )\n })}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.empty', 'No cached responses for this tenant.')}\n </p>\n )}\n </div>\n {ConfirmDialogElement}\n </section>\n )\n}\n\nexport default CachePanel\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { hasFeature } from '@open-mercato/shared/security/features'\n\nconst MANAGE_FEATURE = 'configs.cache.manage'\n\nconst API_PATH = '/api/configs/cache'\nconst CACHE_MUTATION_CONTEXT_ID = 'configs-cache-panel'\n\ntype CrudCacheSegment = {\n segment: string\n resource: string | null\n method: string | null\n path: string | null\n keyCount: number\n}\n\ntype CrudCacheStats = {\n generatedAt: string\n totalKeys: number\n segments: CrudCacheSegment[]\n}\n\ntype FetchState = {\n loading: boolean\n error: string | null\n stats: CrudCacheStats | null\n}\n\nexport function CachePanel() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [state, setState] = React.useState<FetchState>({ loading: true, error: null, stats: null })\n const [canManage, setCanManage] = React.useState(false)\n const [checkingFeature, setCheckingFeature] = React.useState(true)\n const [purgingAll, setPurgingAll] = React.useState(false)\n const [segmentPurges, setSegmentPurges] = React.useState<Record<string, boolean>>({})\n\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: CACHE_MUTATION_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const cacheMutationContext = React.useMemo(\n () => ({\n formId: CACHE_MUTATION_CONTEXT_ID,\n resourceKind: 'configs.cache',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n\n const loadStats = React.useCallback(async () => {\n setState((current) => ({ ...current, loading: true, error: null }))\n try {\n const stats = await readApiResultOrThrow<CrudCacheStats>(API_PATH, undefined, {\n errorMessage: t('configs.cache.loadError', 'Failed to load cache statistics.'),\n })\n setState({ loading: false, error: null, stats })\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.cache.loadError', 'Failed to load cache statistics.')\n setState({ loading: false, error: message, stats: null })\n }\n }, [t])\n\n React.useEffect(() => {\n loadStats().catch(() => {})\n }, [loadStats])\n\n React.useEffect(() => {\n let cancelled = false\n async function checkManageFeature() {\n try {\n const payload = await readApiResultOrThrow<{ ok?: boolean; granted?: unknown }>(\n '/api/auth/feature-check',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: [MANAGE_FEATURE] }),\n },\n {\n errorMessage: t('configs.cache.loadError', 'Failed to load cache statistics.'),\n allowNullResult: true,\n },\n )\n if (cancelled) return\n const granted = Array.isArray(payload?.granted)\n ? (payload.granted as unknown[]).filter((feature) => typeof feature === 'string') as string[]\n : []\n const canManageFeature = payload?.ok === true || hasFeature(granted, MANAGE_FEATURE)\n setCanManage(canManageFeature)\n } catch {\n if (!cancelled) setCanManage(false)\n } finally {\n if (!cancelled) setCheckingFeature(false)\n }\n }\n checkManageFeature().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [t])\n\n const handleRefresh = React.useCallback(() => {\n loadStats().catch(() => {})\n }, [loadStats])\n\n const handlePurgeAll = React.useCallback(async () => {\n if (!canManage || purgingAll) return\n const confirmed = await confirm({\n title: t('configs.cache.purgeAllConfirm', 'Purge all cached entries for this tenant?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPurgingAll(true)\n try {\n const payload = await runMutation({\n operation: () =>\n readApiResultOrThrow<{ stats?: CrudCacheStats }>(\n API_PATH,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ action: 'purgeAll' }),\n },\n {\n errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),\n allowNullResult: true,\n },\n ),\n context: cacheMutationContext,\n mutationPayload: { action: 'purgeAll' },\n })\n const stats = payload?.stats\n if (stats) {\n setState({ loading: false, error: null, stats })\n } else {\n handleRefresh()\n }\n flash(t('configs.cache.purgeAllSuccess', 'Cache cleared.'), 'success')\n setSegmentPurges({})\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.cache.purgeError', 'Failed to purge cache segment.')\n flash(message, 'error')\n } finally {\n setPurgingAll(false)\n }\n }, [canManage, confirm, purgingAll, t, handleRefresh, runMutation, cacheMutationContext]);\n\n\n const handlePurgeSegment = React.useCallback(async (segment: string) => {\n if (!canManage || segmentPurges[segment]) return\n const confirmed = await confirm({\n title: t('configs.cache.purgeSegmentConfirm', 'Purge cached entries for this segment?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setSegmentPurges((prev) => ({ ...prev, [segment]: true }))\n try {\n const payload = await runMutation({\n operation: () =>\n readApiResultOrThrow<{ stats?: CrudCacheStats; deleted?: number }>(\n API_PATH,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ action: 'purgeSegment', segment }),\n },\n {\n errorMessage: t('configs.cache.purgeError', 'Failed to purge cache segment.'),\n allowNullResult: true,\n },\n ),\n context: cacheMutationContext,\n mutationPayload: { action: 'purgeSegment', segment },\n })\n const stats = payload?.stats\n if (stats) {\n setState({ loading: false, error: null, stats })\n } else {\n handleRefresh()\n }\n const deleted = typeof payload?.deleted === 'number' ? payload.deleted : 0\n flash(\n t('configs.cache.purgeSegmentSuccess', {\n segment,\n count: deleted,\n }),\n 'success'\n )\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.cache.purgeError', 'Failed to purge cache segment.')\n flash(message, 'error')\n } finally {\n setSegmentPurges((prev) => {\n const next = { ...prev }\n delete next[segment]\n return next\n })\n }\n }, [canManage, confirm, segmentPurges, t, handleRefresh, runMutation, cacheMutationContext]);\n\n if (state.loading) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n {ConfirmDialogElement}\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.cache.title', 'Cache overview')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}\n </p>\n </header>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n {t('configs.cache.loading', 'Loading cache statistics\u2026')}\n </div>\n </section>\n )\n }\n\n if (state.error) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n {ConfirmDialogElement}\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.cache.title', 'Cache overview')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}\n </p>\n </header>\n <ErrorMessage label={state.error} />\n <div className=\"flex flex-wrap gap-2\">\n <Button variant=\"outline\" type=\"button\" onClick={handleRefresh}>\n {t('configs.cache.retry', 'Retry')}\n </Button>\n </div>\n </section>\n )\n }\n\n const stats = state.stats\n const canShowActions = !checkingFeature && canManage\n\n return (\n <section className=\"space-y-6 rounded-lg border bg-background p-6\">\n <header className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.cache.title', 'Cache overview')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}\n </p>\n {stats ? (\n <>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.cache.generatedAt',\n 'Stats generated {{timestamp}}',\n { timestamp: new Date(stats.generatedAt).toLocaleString() }\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.cache.totalEntries',\n '{{count}} cached entries',\n { count: stats.totalKeys }\n )}\n </p>\n </>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" type=\"button\" onClick={handleRefresh}>\n {t('configs.cache.refresh', 'Refresh')}\n </Button>\n {canShowActions ? (\n <Button variant=\"destructive\" type=\"button\" disabled={purgingAll} onClick={() => { void handlePurgeAll() }}>\n {purgingAll\n ? t('configs.cache.purgeAllLoading', 'Purging\u2026')\n : t('configs.cache.purgeAll', 'Purge all cache')}\n </Button>\n ) : null}\n </div>\n </header>\n <div className=\"space-y-4 rounded-lg border bg-card p-4\">\n {stats && stats.segments.length ? (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[560px] text-sm\">\n <thead>\n <tr className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.segment', 'Segment')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.path', 'Path')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.method', 'Method')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('configs.cache.table.count', 'Cached keys')}\n </th>\n {canShowActions ? (\n <th className=\"px-3 py-2 text-right\">\n {t('configs.cache.table.actions', 'Actions')}\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody>\n {stats.segments.map((segment) => {\n const isPurging = !!segmentPurges[segment.segment]\n return (\n <tr key={segment.segment} className=\"border-t\">\n <td className=\"px-3 py-2 align-top font-medium\">\n <div className=\"flex flex-col\">\n <span>{segment.segment}</span>\n {segment.resource ? (\n <span className=\"text-xs text-muted-foreground\">{segment.resource}</span>\n ) : null}\n </div>\n </td>\n <td className=\"px-3 py-2 align-top\">\n <code className=\"text-xs text-muted-foreground\">\n {segment.path ?? t('configs.cache.table.pathUnknown', 'n/a')}\n </code>\n </td>\n <td className=\"px-3 py-2 align-top\">\n <span className=\"text-xs uppercase text-muted-foreground\">\n {segment.method ?? 'GET'}\n </span>\n </td>\n <td className=\"px-3 py-2 align-top\">\n {t('configs.cache.table.countValue', '{{count}} keys', { count: segment.keyCount })}\n </td>\n {canShowActions ? (\n <td className=\"px-3 py-2 align-top text-right\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n disabled={isPurging}\n onClick={() => { void handlePurgeSegment(segment.segment) }}\n >\n {isPurging\n ? t('configs.cache.purgeSegmentLoading', 'Purging\u2026')\n : t('configs.cache.purgeSegment', 'Purge segment')}\n </Button>\n </td>\n ) : null}\n </tr>\n )\n })}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.cache.empty', 'No cached responses for this tenant.')}\n </p>\n )}\n </div>\n {ConfirmDialogElement}\n </section>\n )\n}\n\nexport default CachePanel\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["stats"]
|
|
7
7
|
}
|
|
@@ -3,6 +3,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
5
5
|
import { Spinner } from "@open-mercato/ui/primitives/spinner";
|
|
6
|
+
import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
|
|
7
|
+
import { ErrorMessage } from "@open-mercato/ui/backend/detail";
|
|
6
8
|
import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
7
9
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
8
10
|
const API_PATH = "/api/configs/system-status";
|
|
@@ -14,12 +16,12 @@ const STATUS_LABEL_KEYS = {
|
|
|
14
16
|
unset: "configs.systemStatus.state.unset",
|
|
15
17
|
unknown: "configs.systemStatus.state.unknown"
|
|
16
18
|
};
|
|
17
|
-
const
|
|
18
|
-
enabled: "
|
|
19
|
-
disabled: "
|
|
20
|
-
set: "
|
|
21
|
-
unset: "
|
|
22
|
-
unknown: "
|
|
19
|
+
const STATUS_BADGE_VARIANTS = {
|
|
20
|
+
enabled: "success",
|
|
21
|
+
disabled: "neutral",
|
|
22
|
+
set: "info",
|
|
23
|
+
unset: "neutral",
|
|
24
|
+
unknown: "warning"
|
|
23
25
|
};
|
|
24
26
|
const RUNTIME_MODE_LABEL_KEYS = {
|
|
25
27
|
development: "configs.systemStatus.runtime.development",
|
|
@@ -63,10 +65,6 @@ function renderEnvAssignment(item, rawValue, translate) {
|
|
|
63
65
|
}
|
|
64
66
|
return /* @__PURE__ */ jsx("code", { className: codeClass, children: `${item.key}=${value}` });
|
|
65
67
|
}
|
|
66
|
-
function StatusBadge({ state }) {
|
|
67
|
-
const t = useT();
|
|
68
|
-
return /* @__PURE__ */ jsx("span", { className: `inline-flex items-center rounded-full px-3 py-1 text-xs font-medium ${STATUS_BADGE_CLASSES[state]}`, children: t(STATUS_LABEL_KEYS[state]) });
|
|
69
|
-
}
|
|
70
68
|
function SystemStatusPanel() {
|
|
71
69
|
const t = useT();
|
|
72
70
|
const [state, setState] = React.useState({ loading: true, error: null, snapshot: null });
|
|
@@ -118,7 +116,7 @@ function SystemStatusPanel() {
|
|
|
118
116
|
"Review debugging, cache, and logging flags that shape backend behaviour."
|
|
119
117
|
) })
|
|
120
118
|
] }),
|
|
121
|
-
/* @__PURE__ */ jsx(
|
|
119
|
+
/* @__PURE__ */ jsx(ErrorMessage, { label: state.error }),
|
|
122
120
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => loadSnapshot().catch(() => {
|
|
123
121
|
}), children: t("configs.systemStatus.retry", "Retry") })
|
|
124
122
|
] });
|
|
@@ -151,7 +149,7 @@ function SystemStatusPanel() {
|
|
|
151
149
|
/* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold", children: t(item.labelKey) }),
|
|
152
150
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t(item.descriptionKey) })
|
|
153
151
|
] }),
|
|
154
|
-
/* @__PURE__ */ jsx(StatusBadge, { state: item.state })
|
|
152
|
+
/* @__PURE__ */ jsx(StatusBadge, { variant: STATUS_BADGE_VARIANTS[item.state], children: t(STATUS_LABEL_KEYS[item.state]) })
|
|
155
153
|
] }),
|
|
156
154
|
/* @__PURE__ */ jsxs("dl", { className: "grid gap-3 text-sm sm:grid-cols-2", children: [
|
|
157
155
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/configs/components/SystemStatusPanel.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type {\n SystemStatusSnapshot,\n SystemStatusItem,\n SystemStatusState,\n SystemStatusRuntimeMode,\n} from '../lib/system-status.types'\n\nconst API_PATH = '/api/configs/system-status'\nconst ENV_GUIDE_URL = 'https://docs.openmercato.com/docs/framework/operations/system-status#managing-variables'\n\nconst STATUS_LABEL_KEYS: Record<SystemStatusState, string> = {\n enabled: 'configs.systemStatus.state.enabled',\n disabled: 'configs.systemStatus.state.disabled',\n set: 'configs.systemStatus.state.set',\n unset: 'configs.systemStatus.state.unset',\n unknown: 'configs.systemStatus.state.unknown',\n}\n\nconst STATUS_BADGE_CLASSES: Record<SystemStatusState, string> = {\n enabled: 'border border-emerald-300 bg-emerald-50 text-emerald-700',\n disabled: 'border border-slate-300 bg-slate-100 text-slate-700',\n set: 'border border-blue-300 bg-blue-50 text-blue-700',\n unset: 'border border-dashed border-slate-200 text-slate-500',\n unknown: 'border border-amber-300 bg-amber-50 text-amber-700',\n}\n\nconst RUNTIME_MODE_LABEL_KEYS: Record<SystemStatusRuntimeMode, string> = {\n development: 'configs.systemStatus.runtime.development',\n production: 'configs.systemStatus.runtime.production',\n test: 'configs.systemStatus.runtime.test',\n unknown: 'configs.systemStatus.runtime.unknown',\n}\n\nconst KNOWN_RUNTIME_MODES = new Set<SystemStatusRuntimeMode>(['development', 'production', 'test', 'unknown'])\n\nfunction isSystemStatusSnapshot(payload: unknown): payload is SystemStatusSnapshot {\n if (!payload || typeof payload !== 'object') return false\n const value = payload as { categories?: unknown; runtimeMode?: unknown }\n if (!Array.isArray(value.categories)) return false\n if (typeof value.runtimeMode !== 'string') return false\n if (!KNOWN_RUNTIME_MODES.has(value.runtimeMode as SystemStatusRuntimeMode)) return false\n return value.categories.every((category) => {\n if (!category || typeof category !== 'object') return false\n const entry = category as { key?: unknown; items?: unknown }\n if (typeof entry.key !== 'string') return false\n if (!Array.isArray(entry.items)) return false\n return entry.items.every((item) => {\n if (!item || typeof item !== 'object') return false\n const asItem = item as { key?: unknown; state?: unknown }\n return typeof asItem.key === 'string' && typeof asItem.state === 'string'\n })\n })\n}\n\nfunction renderEnvAssignment(\n item: SystemStatusItem,\n rawValue: string | null | undefined,\n translate: (key: string, fallback?: string) => string,\n): React.ReactNode {\n const value = typeof rawValue === 'string' ? rawValue : ''\n const hasValue = value.trim().length > 0\n const codeClass =\n 'block w-full break-all whitespace-pre-wrap rounded bg-muted px-1.5 py-0.5 font-mono text-xs sm:text-sm'\n if (!hasValue) {\n const notSet = translate('configs.systemStatus.value.notSet', 'Not set')\n return (\n <div className=\"space-y-1\">\n <code className={codeClass}>{item.key}</code>\n <span className=\"text-xs text-muted-foreground sm:text-sm\">({notSet})</span>\n </div>\n )\n }\n return (\n <code className={codeClass}>\n {`${item.key}=${value}`}\n </code>\n )\n}\n\nfunction StatusBadge({ state }: { state: SystemStatusState }) {\n const t = useT()\n return (\n <span className={`inline-flex items-center rounded-full px-3 py-1 text-xs font-medium ${STATUS_BADGE_CLASSES[state]}`}>\n {t(STATUS_LABEL_KEYS[state])}\n </span>\n )\n}\n\ntype FetchState = {\n loading: boolean\n error: string | null\n snapshot: SystemStatusSnapshot | null\n}\n\nexport function SystemStatusPanel() {\n const t = useT()\n const [state, setState] = React.useState<FetchState>({ loading: true, error: null, snapshot: null })\n\n const loadSnapshot = React.useCallback(async () => {\n setState((current) => ({ ...current, loading: true, error: null }))\n try {\n const payload = await readApiResultOrThrow<unknown>(API_PATH, undefined, {\n errorMessage: t('configs.systemStatus.error', 'Failed to load system status'),\n })\n if (!isSystemStatusSnapshot(payload)) {\n setState({\n loading: false,\n error: t('configs.systemStatus.invalidResponse', 'Unexpected response when loading system status'),\n snapshot: null,\n })\n return\n }\n setState({ loading: false, error: null, snapshot: payload })\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.systemStatus.error', 'Failed to load system status')\n setState({ loading: false, error: message, snapshot: null })\n }\n }, [t])\n\n React.useEffect(() => {\n loadSnapshot().catch(() => {})\n }, [loadSnapshot])\n\n if (state.loading) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.systemStatus.title', 'System status')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'configs.systemStatus.description',\n 'Review debugging, cache, and logging flags that shape backend behaviour.'\n )}\n </p>\n </header>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n {t('configs.systemStatus.loading', 'Loading status snapshot\u2026')}\n </div>\n </section>\n )\n }\n\n if (state.error) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.systemStatus.title', 'System status')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'configs.systemStatus.description',\n 'Review debugging, cache, and logging flags that shape backend behaviour.'\n )}\n </p>\n </header>\n <div className=\"rounded border border-red-200 bg-red-50 p-3 text-sm text-red-700\">\n {state.error}\n </div>\n <Button type=\"button\" variant=\"outline\" onClick={() => loadSnapshot().catch(() => {})}>\n {t('configs.systemStatus.retry', 'Retry')}\n </Button>\n </section>\n )\n }\n\n const snapshot = state.snapshot\n if (!snapshot) return null\n\n return (\n <section className=\"space-y-6 rounded-lg border bg-background p-6\">\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.systemStatus.title', 'System status')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.systemStatus.description', 'Review debugging, cache, and logging flags that shape backend behaviour.')}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.systemStatus.runtimeMode',\n 'Runtime mode: {{mode}}',\n { mode: t(RUNTIME_MODE_LABEL_KEYS[snapshot.runtimeMode]) }\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.systemStatus.generatedAt',\n 'Snapshot generated {{timestamp}}',\n { timestamp: new Date(snapshot.generatedAt).toLocaleString() }\n )}\n </p>\n </header>\n <div className=\"space-y-6\">\n {snapshot.categories.map((category) => (\n <div key={category.key} className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-base font-semibold\">{t(category.labelKey)}</h3>\n {category.descriptionKey ? (\n <p className=\"text-sm text-muted-foreground\">{t(category.descriptionKey)}</p>\n ) : null}\n </div>\n <div className=\"grid gap-4 lg:grid-cols-2\">\n {category.items.map((item) => (\n <article key={item.key} className=\"flex flex-col gap-4 rounded-lg border bg-card p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <h4 className=\"text-sm font-semibold\">{t(item.labelKey)}</h4>\n <p className=\"text-xs text-muted-foreground\">{t(item.descriptionKey)}</p>\n </div>\n <StatusBadge state={item.state} />\n </div>\n <dl className=\"grid gap-3 text-sm sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <dt className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n {t('configs.systemStatus.details.currentValue', 'Current value')}\n </dt>\n <dd className=\"text-sm font-medium\">\n {renderEnvAssignment(item, item.value, t)}\n </dd>\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n {t('configs.systemStatus.details.defaultValue', 'Default')}\n </dt>\n <dd className=\"text-sm font-medium\">\n {renderEnvAssignment(item, item.defaultValue, t)}\n </dd>\n </div>\n </dl>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.systemStatus.details.updateHint',\n 'Update by running `export {{key}}=value` or editing `.env`, then restart the app.',\n { key: item.key }\n )}{' '}\n <a\n href={ENV_GUIDE_URL}\n className=\"font-medium text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {t('configs.systemStatus.details.updateDocs', 'Environment configuration guide')}\n </a>\n </p>\n {item.docUrl ? (\n <div>\n <a\n href={item.docUrl}\n className=\"text-sm font-medium text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {t('configs.systemStatus.viewDocs', 'View documentation')}\n </a>\n </div>\n ) : null}\n </article>\n ))}\n </div>\n </div>\n ))}\n </div>\n </section>\n )\n}\n\nexport default SystemStatusPanel\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { StatusBadge, type StatusMap } from '@open-mercato/ui/primitives/status-badge'\nimport { ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type {\n SystemStatusSnapshot,\n SystemStatusItem,\n SystemStatusState,\n SystemStatusRuntimeMode,\n} from '../lib/system-status.types'\n\nconst API_PATH = '/api/configs/system-status'\nconst ENV_GUIDE_URL = 'https://docs.openmercato.com/docs/framework/operations/system-status#managing-variables'\n\nconst STATUS_LABEL_KEYS: Record<SystemStatusState, string> = {\n enabled: 'configs.systemStatus.state.enabled',\n disabled: 'configs.systemStatus.state.disabled',\n set: 'configs.systemStatus.state.set',\n unset: 'configs.systemStatus.state.unset',\n unknown: 'configs.systemStatus.state.unknown',\n}\n\nconst STATUS_BADGE_VARIANTS: StatusMap<SystemStatusState> = {\n enabled: 'success',\n disabled: 'neutral',\n set: 'info',\n unset: 'neutral',\n unknown: 'warning',\n}\n\nconst RUNTIME_MODE_LABEL_KEYS: Record<SystemStatusRuntimeMode, string> = {\n development: 'configs.systemStatus.runtime.development',\n production: 'configs.systemStatus.runtime.production',\n test: 'configs.systemStatus.runtime.test',\n unknown: 'configs.systemStatus.runtime.unknown',\n}\n\nconst KNOWN_RUNTIME_MODES = new Set<SystemStatusRuntimeMode>(['development', 'production', 'test', 'unknown'])\n\nfunction isSystemStatusSnapshot(payload: unknown): payload is SystemStatusSnapshot {\n if (!payload || typeof payload !== 'object') return false\n const value = payload as { categories?: unknown; runtimeMode?: unknown }\n if (!Array.isArray(value.categories)) return false\n if (typeof value.runtimeMode !== 'string') return false\n if (!KNOWN_RUNTIME_MODES.has(value.runtimeMode as SystemStatusRuntimeMode)) return false\n return value.categories.every((category) => {\n if (!category || typeof category !== 'object') return false\n const entry = category as { key?: unknown; items?: unknown }\n if (typeof entry.key !== 'string') return false\n if (!Array.isArray(entry.items)) return false\n return entry.items.every((item) => {\n if (!item || typeof item !== 'object') return false\n const asItem = item as { key?: unknown; state?: unknown }\n return typeof asItem.key === 'string' && typeof asItem.state === 'string'\n })\n })\n}\n\nfunction renderEnvAssignment(\n item: SystemStatusItem,\n rawValue: string | null | undefined,\n translate: (key: string, fallback?: string) => string,\n): React.ReactNode {\n const value = typeof rawValue === 'string' ? rawValue : ''\n const hasValue = value.trim().length > 0\n const codeClass =\n 'block w-full break-all whitespace-pre-wrap rounded bg-muted px-1.5 py-0.5 font-mono text-xs sm:text-sm'\n if (!hasValue) {\n const notSet = translate('configs.systemStatus.value.notSet', 'Not set')\n return (\n <div className=\"space-y-1\">\n <code className={codeClass}>{item.key}</code>\n <span className=\"text-xs text-muted-foreground sm:text-sm\">({notSet})</span>\n </div>\n )\n }\n return (\n <code className={codeClass}>\n {`${item.key}=${value}`}\n </code>\n )\n}\n\ntype FetchState = {\n loading: boolean\n error: string | null\n snapshot: SystemStatusSnapshot | null\n}\n\nexport function SystemStatusPanel() {\n const t = useT()\n const [state, setState] = React.useState<FetchState>({ loading: true, error: null, snapshot: null })\n\n const loadSnapshot = React.useCallback(async () => {\n setState((current) => ({ ...current, loading: true, error: null }))\n try {\n const payload = await readApiResultOrThrow<unknown>(API_PATH, undefined, {\n errorMessage: t('configs.systemStatus.error', 'Failed to load system status'),\n })\n if (!isSystemStatusSnapshot(payload)) {\n setState({\n loading: false,\n error: t('configs.systemStatus.invalidResponse', 'Unexpected response when loading system status'),\n snapshot: null,\n })\n return\n }\n setState({ loading: false, error: null, snapshot: payload })\n } catch (error) {\n const message =\n error instanceof Error && error.message\n ? error.message\n : t('configs.systemStatus.error', 'Failed to load system status')\n setState({ loading: false, error: message, snapshot: null })\n }\n }, [t])\n\n React.useEffect(() => {\n loadSnapshot().catch(() => {})\n }, [loadSnapshot])\n\n if (state.loading) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.systemStatus.title', 'System status')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'configs.systemStatus.description',\n 'Review debugging, cache, and logging flags that shape backend behaviour.'\n )}\n </p>\n </header>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n {t('configs.systemStatus.loading', 'Loading status snapshot\u2026')}\n </div>\n </section>\n )\n }\n\n if (state.error) {\n return (\n <section className=\"space-y-3 rounded-lg border bg-background p-6\">\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.systemStatus.title', 'System status')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'configs.systemStatus.description',\n 'Review debugging, cache, and logging flags that shape backend behaviour.'\n )}\n </p>\n </header>\n <ErrorMessage label={state.error} />\n <Button type=\"button\" variant=\"outline\" onClick={() => loadSnapshot().catch(() => {})}>\n {t('configs.systemStatus.retry', 'Retry')}\n </Button>\n </section>\n )\n }\n\n const snapshot = state.snapshot\n if (!snapshot) return null\n\n return (\n <section className=\"space-y-6 rounded-lg border bg-background p-6\">\n <header className=\"space-y-1\">\n <h2 className=\"text-lg font-semibold\">{t('configs.systemStatus.title', 'System status')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('configs.systemStatus.description', 'Review debugging, cache, and logging flags that shape backend behaviour.')}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.systemStatus.runtimeMode',\n 'Runtime mode: {{mode}}',\n { mode: t(RUNTIME_MODE_LABEL_KEYS[snapshot.runtimeMode]) }\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.systemStatus.generatedAt',\n 'Snapshot generated {{timestamp}}',\n { timestamp: new Date(snapshot.generatedAt).toLocaleString() }\n )}\n </p>\n </header>\n <div className=\"space-y-6\">\n {snapshot.categories.map((category) => (\n <div key={category.key} className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-base font-semibold\">{t(category.labelKey)}</h3>\n {category.descriptionKey ? (\n <p className=\"text-sm text-muted-foreground\">{t(category.descriptionKey)}</p>\n ) : null}\n </div>\n <div className=\"grid gap-4 lg:grid-cols-2\">\n {category.items.map((item) => (\n <article key={item.key} className=\"flex flex-col gap-4 rounded-lg border bg-card p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <h4 className=\"text-sm font-semibold\">{t(item.labelKey)}</h4>\n <p className=\"text-xs text-muted-foreground\">{t(item.descriptionKey)}</p>\n </div>\n <StatusBadge variant={STATUS_BADGE_VARIANTS[item.state]}>\n {t(STATUS_LABEL_KEYS[item.state])}\n </StatusBadge>\n </div>\n <dl className=\"grid gap-3 text-sm sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <dt className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n {t('configs.systemStatus.details.currentValue', 'Current value')}\n </dt>\n <dd className=\"text-sm font-medium\">\n {renderEnvAssignment(item, item.value, t)}\n </dd>\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n {t('configs.systemStatus.details.defaultValue', 'Default')}\n </dt>\n <dd className=\"text-sm font-medium\">\n {renderEnvAssignment(item, item.defaultValue, t)}\n </dd>\n </div>\n </dl>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'configs.systemStatus.details.updateHint',\n 'Update by running `export {{key}}=value` or editing `.env`, then restart the app.',\n { key: item.key }\n )}{' '}\n <a\n href={ENV_GUIDE_URL}\n className=\"font-medium text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {t('configs.systemStatus.details.updateDocs', 'Environment configuration guide')}\n </a>\n </p>\n {item.docUrl ? (\n <div>\n <a\n href={item.docUrl}\n className=\"text-sm font-medium text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {t('configs.systemStatus.viewDocs', 'View documentation')}\n </a>\n </div>\n ) : null}\n </article>\n ))}\n </div>\n </div>\n ))}\n </div>\n </section>\n )\n}\n\nexport default SystemStatusPanel\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -29,6 +29,12 @@ __decorateClass([
|
|
|
29
29
|
__decorateClass([
|
|
30
30
|
Property({ name: "value_json", type: "json", nullable: true })
|
|
31
31
|
], ModuleConfig.prototype, "valueJson", 2);
|
|
32
|
+
__decorateClass([
|
|
33
|
+
Property({ name: "organization_id", type: "uuid", nullable: true })
|
|
34
|
+
], ModuleConfig.prototype, "organizationId", 2);
|
|
35
|
+
__decorateClass([
|
|
36
|
+
Property({ name: "tenant_id", type: "uuid", nullable: true })
|
|
37
|
+
], ModuleConfig.prototype, "tenantId", 2);
|
|
32
38
|
__decorateClass([
|
|
33
39
|
Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
|
|
34
40
|
], ModuleConfig.prototype, "createdAt", 2);
|
|
@@ -37,7 +43,15 @@ __decorateClass([
|
|
|
37
43
|
], ModuleConfig.prototype, "updatedAt", 2);
|
|
38
44
|
ModuleConfig = __decorateClass([
|
|
39
45
|
Entity({ tableName: "module_configs" }),
|
|
40
|
-
|
|
46
|
+
Index({
|
|
47
|
+
name: "module_configs_global_unique",
|
|
48
|
+
expression: 'create unique index "module_configs_global_unique" on "module_configs" ("module_id", "name") where "tenant_id" is null'
|
|
49
|
+
}),
|
|
50
|
+
Index({
|
|
51
|
+
name: "module_configs_scoped_unique",
|
|
52
|
+
expression: 'create unique index "module_configs_scoped_unique" on "module_configs" ("module_id", "name", "tenant_id") where "tenant_id" is not null'
|
|
53
|
+
}),
|
|
54
|
+
Index({ name: "module_configs_module_name_tenant_idx", properties: ["moduleId", "name", "tenantId"] })
|
|
41
55
|
], ModuleConfig);
|
|
42
56
|
OptionalProps;
|
|
43
57
|
let UpgradeActionRun = class {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/configs/data/entities.ts"],
|
|
4
|
-
"sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport { Entity, Index, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'module_configs' })\n@
|
|
5
|
-
"mappings": ";;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,OAAO,YAAY,UAAU,cAAc;
|
|
4
|
+
"sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport { Entity, Index, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'module_configs' })\n@Index({\n name: 'module_configs_global_unique',\n expression:\n 'create unique index \"module_configs_global_unique\" on \"module_configs\" (\"module_id\", \"name\") where \"tenant_id\" is null',\n})\n@Index({\n name: 'module_configs_scoped_unique',\n expression:\n 'create unique index \"module_configs_scoped_unique\" on \"module_configs\" (\"module_id\", \"name\", \"tenant_id\") where \"tenant_id\" is not null',\n})\n@Index({ name: 'module_configs_module_name_tenant_idx', properties: ['moduleId', 'name', 'tenantId'] })\nexport class ModuleConfig {\n [OptionalProps]?: 'createdAt' | 'updatedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'module_id', type: 'text' })\n moduleId!: string\n\n @Property({ name: 'name', type: 'text' })\n name!: string\n\n @Property({ name: 'value_json', type: 'json', nullable: true })\n valueJson!: unknown\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n@Entity({ tableName: 'upgrade_action_runs' })\n@Index({ name: 'upgrade_action_runs_scope_idx', properties: ['organizationId', 'tenantId'] })\n@Unique({ name: 'upgrade_action_runs_action_scope_unique', properties: ['version', 'actionId', 'organizationId', 'tenantId'] })\nexport class UpgradeActionRun {\n [OptionalProps]?: 'createdAt' | 'completedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'version', type: 'text' })\n version!: string\n\n @Property({ name: 'action_id', type: 'text' })\n actionId!: string\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'completed_at', type: Date, onCreate: () => new Date() })\n completedAt: Date = new Date()\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,OAAO,YAAY,UAAU,cAAc;AAezD;AADI,IAAM,eAAN,MAAmB;AAAA,EAAnB;AAsBL,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAC7B;AAtBE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAHlD,aAIX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GANlC,aAOX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,GAT7B,aAUX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAZnD,aAaX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAfxD,aAgBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAlBlD,aAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GArB7D,aAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAxB7D,aAyBX;AAzBW,eAAN;AAAA,EAZN,OAAO,EAAE,WAAW,iBAAiB,CAAC;AAAA,EACtC,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM,EAAE,MAAM,yCAAyC,YAAY,CAAC,YAAY,QAAQ,UAAU,EAAE,CAAC;AAAA,GACzF;AAgCV;AADI,IAAM,mBAAN,MAAuB;AAAA,EAAvB;AAmBL,uBAAoB,oBAAI,KAAK;AAG7B,qBAAkB,oBAAI,KAAK;AAAA;AAC7B;AAnBE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAHlD,iBAIX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,WAAW,MAAM,OAAO,CAAC;AAAA,GANhC,iBAOX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GATlC,iBAUX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,OAAO,CAAC;AAAA,GAZxC,iBAaX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAflC,iBAgBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAlB/D,iBAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GArB7D,iBAsBX;AAtBW,mBAAN;AAAA,EAHN,OAAO,EAAE,WAAW,sBAAsB,CAAC;AAAA,EAC3C,MAAM,EAAE,MAAM,iCAAiC,YAAY,CAAC,kBAAkB,UAAU,EAAE,CAAC;AAAA,EAC3F,OAAO,EAAE,MAAM,2CAA2C,YAAY,CAAC,WAAW,YAAY,kBAAkB,UAAU,EAAE,CAAC;AAAA,GACjH;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|