diff --git a/package-lock.json b/package-lock.json index 482203dd..913df594 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,22 +10,22 @@ "license": "MIT", "dependencies": { "@solid/better-simple-slideshow": "^0.1.0", - "activitystreams-pane": "1.0.3-4", - "chat-pane": "3.0.4-3", + "activitystreams-pane": "2.0.0-0", + "chat-pane": "4.0.0-0", "contacts-pane": "3.2.1-6", "dompurify": "^3.4.4", "folder-pane": "3.1.1-3", - "issue-pane": "3.0.3-1", + "issue-pane": "4.0.0-0", "lit-html": "^3.3.2", "marked": "^18.0.3", - "meeting-pane": "3.0.3-1", + "meeting-pane": "4.0.0-0", "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "profile-pane": "3.2.3-4", "rdflib": "2.4.0", - "solid-logic": "4.0.8-3", + "solid-logic": "6.0.0-0", "solid-namespace": "^0.5.4", - "solid-ui": "3.1.3-17", + "solid-ui": "5.0.0-0", "source-pane": "3.1.1-7" }, "devDependencies": { @@ -3010,9 +3010,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.144.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.144.0.tgz", - "integrity": "sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==", + "version": "0.146.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.146.0.tgz", + "integrity": "sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" @@ -3060,10 +3060,26 @@ "@types/node": "*" } }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz", + "integrity": "sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.4.tgz", - "integrity": "sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz", + "integrity": "sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==", "cpu": [ "arm64" ], @@ -3077,9 +3093,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz", + "integrity": "sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==", "cpu": [ "arm64" ], @@ -3093,9 +3109,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.4.tgz", - "integrity": "sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz", + "integrity": "sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==", "cpu": [ "x64" ], @@ -3109,9 +3125,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.4.tgz", - "integrity": "sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz", + "integrity": "sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==", "cpu": [ "x64" ], @@ -3125,9 +3141,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.4.tgz", - "integrity": "sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz", + "integrity": "sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==", "cpu": [ "arm" ], @@ -3141,9 +3157,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.4.tgz", - "integrity": "sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz", + "integrity": "sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==", "cpu": [ "arm64" ], @@ -3157,9 +3173,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.4.tgz", - "integrity": "sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz", + "integrity": "sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==", "cpu": [ "arm64" ], @@ -3173,9 +3189,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.4.tgz", - "integrity": "sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz", + "integrity": "sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==", "cpu": [ "ppc64" ], @@ -3189,9 +3205,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.4.tgz", - "integrity": "sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz", + "integrity": "sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==", "cpu": [ "s390x" ], @@ -3205,9 +3221,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.4.tgz", - "integrity": "sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz", + "integrity": "sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==", "cpu": [ "x64" ], @@ -3221,9 +3237,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.4.tgz", - "integrity": "sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz", + "integrity": "sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==", "cpu": [ "x64" ], @@ -3237,9 +3253,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.4.tgz", - "integrity": "sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz", + "integrity": "sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==", "cpu": [ "arm64" ], @@ -3253,9 +3269,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.4.tgz", - "integrity": "sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz", + "integrity": "sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==", "cpu": [ "arm64" ], @@ -3269,9 +3285,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.4.tgz", - "integrity": "sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz", + "integrity": "sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==", "cpu": [ "x64" ], @@ -3806,14 +3822,14 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", - "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.11.tgz", + "integrity": "sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==", "devOptional": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.10", + "@vitest/utils": "4.1.11", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -3827,8 +3843,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.10", - "vitest": "4.1.10" + "@vitest/browser": "4.1.11", + "vitest": "4.1.11" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -3837,15 +3853,15 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", - "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", + "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -3854,12 +3870,12 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", - "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", + "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.10", + "@vitest/spy": "4.1.11", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -3880,9 +3896,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", "license": "MIT", "dependencies": { "tinyrainbow": "^3.1.0" @@ -3892,12 +3908,12 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", - "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", + "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.10", + "@vitest/utils": "4.1.11", "pathe": "^2.0.3" }, "funding": { @@ -3905,13 +3921,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", - "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", + "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/pretty-format": "4.1.11", + "@vitest/utils": "4.1.11", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -3920,21 +3936,21 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", - "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", + "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", + "@vitest/pretty-format": "4.1.11", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -4029,64 +4045,22 @@ } }, "node_modules/activitystreams-pane": { - "version": "1.0.3-4", - "resolved": "https://registry.npmjs.org/activitystreams-pane/-/activitystreams-pane-1.0.3-4.tgz", - "integrity": "sha512-ebE4D2mytgUM2cmSEZE7scRnh9sO6R85U6wiwQYUnoOkX7loCthk32buGZCIFjJ7T9jqc4cyDpFTNbO0I7Dstg==", + "version": "2.0.0-0", + "resolved": "https://registry.npmjs.org/activitystreams-pane/-/activitystreams-pane-2.0.0-0.tgz", + "integrity": "sha512-pVPm8x8anDnno7FDd2N9/hj2u5IobhfW2p1b0ueDssjK3ztGjcagwcCqXidSI2gEnNdMt46pqLAuepCE20gn0A==", "license": "MIT", "dependencies": { - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "patch-package": "^8.0.1", "rdflib": "2.4.0", "react": "^19.2.3", "react-dom": "^19.2.3", "react-jss": "^10.10.0", - "solid-logic": "4.0.8-1", - "solid-ui": "3.1.3-9", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0", "timeago.js": "^4.0.2" } }, - "node_modules/activitystreams-pane/node_modules/solid-logic": { - "version": "4.0.8-1", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", - "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/activitystreams-pane/node_modules/solid-ui": { - "version": "3.1.3-9", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-9.tgz", - "integrity": "sha512-36as6RIBflm2gsIFnEPLH6hzykXxyc9yJlhJ+E0E6JSLOyjgENGxEj55hMH8lIXzBcR5tkym3Y61vgMm/LIU8Q==", - "license": "MIT", - "dependencies": { - "@awesome.me/webawesome": "^3.9.0", - "@lit/context": "^1.1.6", - "@noble/curves": "^2.2.0", - "@noble/hashes": "^2.2.0", - "escape-html": "^1.0.3", - "lit": "^3.3.3", - "mime-types": "^3.0.2", - "pane-registry": "3.1.2-1", - "rdflib": "2.4.0", - "solid-logic": "4.0.8-1", - "solid-namespace": "^0.5.4", - "uuid": "^14.0.0" - }, - "optionalDependencies": { - "fsevents": "*" - } - }, - "node_modules/activitystreams-pane/node_modules/solid-ui/node_modules/pane-registry": { - "version": "3.1.2-1", - "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-1.tgz", - "integrity": "sha512-aibuyF8pAgHDnmywsMEKUddIcqC0oPF8fNx2TP7zRpRW9aYk2iv06td+br8wenbmu2V/l6Y6aJmCkckHWN/GpA==", - "license": "MIT" - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -4435,9 +4409,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.11.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.15.tgz", - "integrity": "sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA==", + "version": "2.11.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.16.tgz", + "integrity": "sha512-H/bNPUFHewJHyCTdjn1n3Pit5+2GmWT6mmeHImPX+8MA9NA6b67jO4gYmi4jTbCJb2otq34KMZnovndDPqJwhQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4672,58 +4646,20 @@ } }, "node_modules/chat-pane": { - "version": "3.0.4-3", - "resolved": "https://registry.npmjs.org/chat-pane/-/chat-pane-3.0.4-3.tgz", - "integrity": "sha512-m099X1Lb1qaOtaYNAaJ+NfqD/TMRnhX3Gfx5Xgb2HoZYllaxn1xN3Y5Am4Un21k6tLoPaiq1OIkBe09/gHN/sw==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/chat-pane/-/chat-pane-4.0.0-0.tgz", + "integrity": "sha512-MB1Pg8f76RnqcCrRMEpoFb/In5HyHyHC1N8LP9cik3F2/CLh1VHvJn7y6Yhc645okW0NfXGdVaUaI1kTd0R+AA==", "license": "MIT", "dependencies": { - "pane-registry": "3.1.2-2", "patch-package": "^8.0.1", - "rdflib": "^2.3.9", - "solid-logic": "^4.0.8-0", - "solid-ui": "3.1.3-13", + "rdflib": "^2.4.0", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0", "vite": "^8.0.16", "vitest": "^4.0.18", "vitest-axe": "^0.1.0" } }, - "node_modules/chat-pane/node_modules/solid-logic": { - "version": "4.0.8-1", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", - "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/chat-pane/node_modules/solid-ui": { - "version": "3.1.3-13", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-13.tgz", - "integrity": "sha512-0meJycoMXoelTD06W9A0S9Q4vg0I8BDSsui4BfwocfwFIpEZ02FBFZZf1LcanP7NNpAOs0So6HOQp4QlwSJE3w==", - "license": "MIT", - "dependencies": { - "@awesome.me/webawesome": "^3.9.0", - "@lit/context": "^1.1.6", - "@lit/task": "^1.0.3", - "@noble/curves": "^2.2.0", - "@noble/hashes": "^2.2.0", - "escape-html": "^1.0.3", - "lit": "^3.3.3", - "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", - "rdflib": "2.4.0", - "solid-logic": "4.0.8-1", - "solid-namespace": "^0.5.4", - "uuid": "^14.0.0" - }, - "optionalDependencies": { - "fsevents": "*" - } - }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -5154,9 +5090,9 @@ "license": "MIT" }, "node_modules/dompurify": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz", - "integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.14.tgz", + "integrity": "sha512-dVoH9z+MY+C9IilgGCk3YfFqjLi3fChm2OiKJMzh6axrJ5qwxqWaZamgmHrpv22CN/KdbZJuGEGgfQoL00LTdg==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -5222,9 +5158,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.409", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.409.tgz", - "integrity": "sha512-ChI4N44d0B4A6C8prnNjMOaGgE59fUyEVYcRYm2XEXIjMbbvF5i9UL1cblDbpGqiU0uS8FE8UcKxqZqTXdmzbQ==", + "version": "1.5.411", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.411.tgz", + "integrity": "sha512-gglkxzokjHfawpGxq75XdBV2/l3BAPzrsMs70qgaZdTW5rpV1tC4MdgJVP9fN126bODA4ZJQkn1wryEzJyQXIg==", "dev": true, "license": "ISC" }, @@ -6070,6 +6006,29 @@ "vitest-axe": "^0.1.0" } }, + "node_modules/folder-pane/node_modules/pane-registry": { + "version": "3.1.2-2", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-2.tgz", + "integrity": "sha512-w+pCan1Umj+pLm5/uNlBMLw0YOKbKhHn5Qh62oqlKlbFrSHj4H3gNOXcKnI47liQFPQYepw5UPssP3aPdiowvA==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.0", + "solid-logic": "4.0.8-1" + } + }, + "node_modules/folder-pane/node_modules/pane-registry/node_modules/solid-logic": { + "version": "4.0.8-1", + "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", + "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", + "license": "MIT", + "dependencies": { + "@uvdsl/solid-oidc-client-browser": "^0.2.3", + "solid-namespace": "^0.5.4" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/folder-pane/node_modules/solid-logic": { "version": "4.0.8-2", "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-2.tgz", @@ -7296,13 +7255,16 @@ "license": "ISC" }, "node_modules/issue-pane": { - "version": "3.0.3-1", - "resolved": "https://registry.npmjs.org/issue-pane/-/issue-pane-3.0.3-1.tgz", - "integrity": "sha512-oB5Kqxn6px09hIv6wG4cTUt/H6q+MZsAmtp40HNQX2F515xmUYSakufliuQ0ONF30EVxjLGzJVB/X4xKYVZxpQ==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/issue-pane/-/issue-pane-4.0.0-0.tgz", + "integrity": "sha512-vA0Tlq4s1gTKRZNPNRitXfeV4fXoJtLlnH6kGWMe2Lx5eL+ziMAp1LZTsTdclQffxzm1q8COnXCFGrOdhDoc/Q==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", - "patch-package": "^8.0.1" + "patch-package": "^8.0.1", + "rdflib": "2.4.0", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0" }, "engines": { "node": ">=20.19.2" @@ -8246,12 +8208,15 @@ "license": "CC0-1.0" }, "node_modules/meeting-pane": { - "version": "3.0.3-1", - "resolved": "https://registry.npmjs.org/meeting-pane/-/meeting-pane-3.0.3-1.tgz", - "integrity": "sha512-3oAWpeurkBjWDuLlCAGrZGNu0+dJjTBkX2Ymrd97g0uQbnvLol38CCxf8/yhWGCFXs4NtICummRLctR4kgp9kA==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/meeting-pane/-/meeting-pane-4.0.0-0.tgz", + "integrity": "sha512-l8+o/WXp0v0myGzKtgxgVQJJYLV48h8zB4hiJY+Adl9l6CmS4kRq5A6awPVDvSZVjuBaBTxpJ7+Q97nQnqgMUA==", "license": "MIT", "dependencies": { - "patch-package": "^8.0.1" + "patch-package": "^8.0.1", + "rdflib": "2.4.0", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0" } }, "node_modules/micromatch": { @@ -8376,9 +8341,9 @@ "license": "MIT" }, "node_modules/n3": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/n3/-/n3-2.2.0.tgz", - "integrity": "sha512-K/Orb5XrUPocfYfhUT+muvK1I0n2AvVMt93fIExlgjo23u7q0lU0eIFrhBJqooyFWAnpEBz3QZqjHzEHMs1RZg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/n3/-/n3-2.2.5.tgz", + "integrity": "sha512-lR/0N7zVayC6N0uWqrMkPpJn8Up4+qBsjWiBnoOWWEi/ldTcygs2Dw1iAgozzDXLW/fcxXFfbMzpGHlc/1MBLQ==", "license": "MIT", "dependencies": { "buffer": "^6.0.3", @@ -8981,26 +8946,13 @@ } }, "node_modules/pane-registry": { - "version": "3.1.2-2", - "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-2.tgz", - "integrity": "sha512-w+pCan1Umj+pLm5/uNlBMLw0YOKbKhHn5Qh62oqlKlbFrSHj4H3gNOXcKnI47liQFPQYepw5UPssP3aPdiowvA==", + "version": "5.0.0-0", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-5.0.0-0.tgz", + "integrity": "sha512-Yb+qcM4fIDFHxF9CM9PkhIAR1BteaRUCUpmoPOZyGVkqAs4pRbpKsh1QKr0r+ibfTnNUZZ2uBfybg1QUVlmlLA==", "license": "MIT", "dependencies": { "rdflib": "2.4.0", - "solid-logic": "4.0.8-1" - } - }, - "node_modules/pane-registry/node_modules/solid-logic": { - "version": "4.0.8-1", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", - "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4" - }, - "engines": { - "node": ">=18" + "solid-logic": "6.0.0-0" } }, "node_modules/parent-module": { @@ -9360,6 +9312,32 @@ "vitest-axe": "^0.1.0" } }, + "node_modules/profile-pane/node_modules/chat-pane": { + "version": "3.0.4-3", + "resolved": "https://registry.npmjs.org/chat-pane/-/chat-pane-3.0.4-3.tgz", + "integrity": "sha512-m099X1Lb1qaOtaYNAaJ+NfqD/TMRnhX3Gfx5Xgb2HoZYllaxn1xN3Y5Am4Un21k6tLoPaiq1OIkBe09/gHN/sw==", + "license": "MIT", + "dependencies": { + "pane-registry": "3.1.2-2", + "patch-package": "^8.0.1", + "rdflib": "^2.3.9", + "solid-logic": "^4.0.8-0", + "solid-ui": "3.1.3-13", + "vite": "^8.0.16", + "vitest": "^4.0.18", + "vitest-axe": "^0.1.0" + } + }, + "node_modules/profile-pane/node_modules/pane-registry": { + "version": "3.1.2-2", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-2.tgz", + "integrity": "sha512-w+pCan1Umj+pLm5/uNlBMLw0YOKbKhHn5Qh62oqlKlbFrSHj4H3gNOXcKnI47liQFPQYepw5UPssP3aPdiowvA==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.0", + "solid-logic": "4.0.8-1" + } + }, "node_modules/profile-pane/node_modules/solid-logic": { "version": "4.0.8-1", "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", @@ -9863,12 +9841,12 @@ } }, "node_modules/rolldown": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.4.tgz", - "integrity": "sha512-rSr7irW0K7QRWzjdJXqZowkcRdDtjRduh43rBltnVKd0VFq839l1lJoDvGJb6gl7+4rTTCrPWu+YfujUL8Ug7w==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.5.tgz", + "integrity": "sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.144.0", + "@oxc-project/types": "=0.146.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -9878,20 +9856,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.2.4", - "@rolldown/binding-darwin-arm64": "1.2.4", - "@rolldown/binding-darwin-x64": "1.2.4", - "@rolldown/binding-freebsd-x64": "1.2.4", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.4", - "@rolldown/binding-linux-arm64-gnu": "1.2.4", - "@rolldown/binding-linux-arm64-musl": "1.2.4", - "@rolldown/binding-linux-ppc64-gnu": "1.2.4", - "@rolldown/binding-linux-s390x-gnu": "1.2.4", - "@rolldown/binding-linux-x64-gnu": "1.2.4", - "@rolldown/binding-linux-x64-musl": "1.2.4", - "@rolldown/binding-openharmony-arm64": "1.2.4", - "@rolldown/binding-win32-arm64-msvc": "1.2.4", - "@rolldown/binding-win32-x64-msvc": "1.2.4" + "@rolldown/binding-android-arm-eabi": "1.2.5", + "@rolldown/binding-android-arm64": "1.2.5", + "@rolldown/binding-darwin-arm64": "1.2.5", + "@rolldown/binding-darwin-x64": "1.2.5", + "@rolldown/binding-freebsd-x64": "1.2.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.5", + "@rolldown/binding-linux-arm64-gnu": "1.2.5", + "@rolldown/binding-linux-arm64-musl": "1.2.5", + "@rolldown/binding-linux-ppc64-gnu": "1.2.5", + "@rolldown/binding-linux-s390x-gnu": "1.2.5", + "@rolldown/binding-linux-x64-gnu": "1.2.5", + "@rolldown/binding-linux-x64-musl": "1.2.5", + "@rolldown/binding-openharmony-arm64": "1.2.5", + "@rolldown/binding-win32-arm64-msvc": "1.2.5", + "@rolldown/binding-win32-x64-msvc": "1.2.5" } }, "node_modules/safe-array-concat": { @@ -10196,9 +10175,9 @@ "license": "MIT" }, "node_modules/solid-logic": { - "version": "4.0.8-3", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-3.tgz", - "integrity": "sha512-0HKcZJb5ZF2MvFzOid26LMilgL6jD1zaRpix5nb2fB1h3H9WB0kquyD/297L6jIiUTIYSMlVb7ivpvkiVNTTNQ==", + "version": "6.0.0-0", + "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-6.0.0-0.tgz", + "integrity": "sha512-ApPkheoF5Nu+7//WkPJw+tHZuGcktJ0lrkvbTsjNb594RW1DFUtLZY+OXRck45GJW0owoyTtJK7A0jZtlA33tw==", "license": "MIT", "dependencies": { "@uvdsl/solid-oidc-client-browser": "^0.2.3", @@ -10217,9 +10196,9 @@ "license": "MIT" }, "node_modules/solid-ui": { - "version": "3.1.3-17", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-17.tgz", - "integrity": "sha512-XVnz8u3lhW0AhmywMlEOif23lYkQcCmWiL5NUf8A5kmz3Ixw3E/qGiqmPpJ8VAOPZhEsj8+G7u+Y6pUDmhrLeA==", + "version": "5.0.0-0", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.0-0.tgz", + "integrity": "sha512-AHHhqeUcggQmudCHKi90ugJMdEHtFsT46MSl7oNbM/TGW2WpkpQv1d17Z4NU1ezq3YFhJPEK7j9iea5Nx5lHMw==", "license": "MIT", "dependencies": { "@awesome.me/webawesome": "^3.9.0", @@ -10242,9 +10221,9 @@ "escape-html": "^1.0.3", "lit": "^3.3.3", "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "rdflib": "2.4.0", - "solid-logic": "4.0.8-3", + "solid-logic": "6.0.0-0", "solid-namespace": "^0.5.4", "uuid": "^14.0.0" }, @@ -10253,9 +10232,9 @@ } }, "node_modules/solidos-toolkit": { - "version": "0.0.0-dev.761b46f81590c0224a612fba4771aa9c84e7944a", - "resolved": "https://registry.npmjs.org/solidos-toolkit/-/solidos-toolkit-0.0.0-dev.761b46f81590c0224a612fba4771aa9c84e7944a.tgz", - "integrity": "sha512-4KXTvJEYBuymrNTJoT15bT2Ml7a6871g4HExEgNNtmnTDhkl6f0H07BChXuotk/awCkJztaE4VHFJgzRqQYcwg==", + "version": "0.0.0-dev.998a984ddf8fda587eedb0c8125cb952ac28d191", + "resolved": "https://registry.npmjs.org/solidos-toolkit/-/solidos-toolkit-0.0.0-dev.998a984ddf8fda587eedb0c8125cb952ac28d191.tgz", + "integrity": "sha512-m2b3sZkKbjV5X/J8N25h3UIbsiQARdnXCGs1AeGqFiueoq8cWm+pdOyPpqiVuqRnnA5osmKG2wovUcBBYumL0Q==", "dev": true, "dependencies": { "@babel/core": "^7.29.0", @@ -10274,10 +10253,10 @@ "vite-plugin-lit-css": "^3.0.0" }, "peerDependencies": { - "pane-registry": "^3.1.1 || ^3.1.2-0", + "pane-registry": "^3.1.1 || ^3.1.2-0 || ^5.0.0 || ^5.0.0-0", "rdflib": "^2.3.6", - "solid-logic": "^4.0.7 || ^4.0.8-0", - "solid-ui": "^3.1.2 || ^3.1.3-0", + "solid-logic": "^4.0.7 || ^4.0.8-0 || ^6.0.0 || ^6.0.0-0", + "solid-ui": "^3.1.2 || ^3.1.3-0 || ^5.0.0 || ^5.0.0-0", "vite": "^8.0.0", "vitest": "^4.0.0" }, @@ -10329,6 +10308,80 @@ "vitest-axe": "^0.1.0" } }, + "node_modules/source-pane/node_modules/pane-registry": { + "version": "3.1.2-2", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-2.tgz", + "integrity": "sha512-w+pCan1Umj+pLm5/uNlBMLw0YOKbKhHn5Qh62oqlKlbFrSHj4H3gNOXcKnI47liQFPQYepw5UPssP3aPdiowvA==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.0", + "solid-logic": "4.0.8-1" + } + }, + "node_modules/source-pane/node_modules/pane-registry/node_modules/solid-logic": { + "version": "4.0.8-1", + "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", + "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", + "license": "MIT", + "dependencies": { + "@uvdsl/solid-oidc-client-browser": "^0.2.3", + "solid-namespace": "^0.5.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-pane/node_modules/solid-logic": { + "version": "4.0.8-3", + "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-3.tgz", + "integrity": "sha512-0HKcZJb5ZF2MvFzOid26LMilgL6jD1zaRpix5nb2fB1h3H9WB0kquyD/297L6jIiUTIYSMlVb7ivpvkiVNTTNQ==", + "license": "MIT", + "dependencies": { + "@uvdsl/solid-oidc-client-browser": "^0.2.3", + "solid-namespace": "^0.5.4", + "vite": "^8.0.16", + "vitest": "^4.1.9" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-pane/node_modules/solid-ui": { + "version": "3.1.3-17", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-17.tgz", + "integrity": "sha512-XVnz8u3lhW0AhmywMlEOif23lYkQcCmWiL5NUf8A5kmz3Ixw3E/qGiqmPpJ8VAOPZhEsj8+G7u+Y6pUDmhrLeA==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "3.1.2-2", + "rdflib": "2.4.0", + "solid-logic": "4.0.8-3", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -11214,9 +11267,9 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz", - "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.2.tgz", + "integrity": "sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -11243,15 +11296,15 @@ } }, "node_modules/vite": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.1.tgz", - "integrity": "sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", "license": "MIT", "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.5", - "postcss": "^8.5.25", - "rolldown": "~1.2.1", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", "tinyglobby": "^0.2.17" }, "bin": { @@ -11268,7 +11321,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.4.0", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -11343,18 +11396,18 @@ } }, "node_modules/vitest": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", - "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.1.10", - "@vitest/mocker": "4.1.10", - "@vitest/pretty-format": "4.1.10", - "@vitest/runner": "4.1.10", - "@vitest/snapshot": "4.1.10", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", + "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.11", + "@vitest/mocker": "4.1.11", + "@vitest/pretty-format": "4.1.11", + "@vitest/runner": "4.1.11", + "@vitest/snapshot": "4.1.11", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -11382,12 +11435,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.10", - "@vitest/browser-preview": "4.1.10", - "@vitest/browser-webdriverio": "4.1.10", - "@vitest/coverage-istanbul": "4.1.10", - "@vitest/coverage-v8": "4.1.10", - "@vitest/ui": "4.1.10", + "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-preview": "4.1.11", + "@vitest/browser-webdriverio": "4.1.11", + "@vitest/coverage-istanbul": "4.1.11", + "@vitest/coverage-v8": "4.1.11", + "@vitest/ui": "4.1.11", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index f74d8e9a..3cbb30a2 100644 --- a/package.json +++ b/package.json @@ -57,22 +57,22 @@ "homepage": "https://github.com/SolidOS/solid-panes", "dependencies": { "@solid/better-simple-slideshow": "^0.1.0", - "activitystreams-pane": "1.0.3-4", - "chat-pane": "3.0.4-3", + "activitystreams-pane": "2.0.0-0", + "chat-pane": "4.0.0-0", "contacts-pane": "3.2.1-6", "dompurify": "^3.4.4", "folder-pane": "3.1.1-3", - "issue-pane": "3.0.3-1", + "issue-pane": "4.0.0-0", "lit-html": "^3.3.2", "marked": "^18.0.3", - "meeting-pane": "3.0.3-1", + "meeting-pane": "4.0.0-0", "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "profile-pane": "3.2.3-4", "rdflib": "2.4.0", - "solid-logic": "4.0.8-3", + "solid-logic": "6.0.0-0", "solid-namespace": "^0.5.4", - "solid-ui": "3.1.3-17", + "solid-ui": "5.0.0-0", "source-pane": "3.1.1-7" }, "overrides": { diff --git a/src/components/file-explorer-header/FileExplorerHeader.styles.css b/src/components/file-explorer-header/FileExplorerHeader.styles.css index d75d59f4..866bd8cb 100644 --- a/src/components/file-explorer-header/FileExplorerHeader.styles.css +++ b/src/components/file-explorer-header/FileExplorerHeader.styles.css @@ -7,6 +7,7 @@ flex-wrap: nowrap; width: 100%; text-align: right; - padding: 15px; + padding: 10px; + border-bottom: 1px solid var(--solid-ui-color-gray-200, #cbd5e1); } } diff --git a/src/components/file-explorer-header/FileExplorerHeader.ts b/src/components/file-explorer-header/FileExplorerHeader.ts index 136cdc3f..9509899a 100644 --- a/src/components/file-explorer-header/FileExplorerHeader.ts +++ b/src/components/file-explorer-header/FileExplorerHeader.ts @@ -10,8 +10,8 @@ import styles from './FileExplorerHeader.styles.css' import './FileExplorerHeaderSummary' import './FileExplorerHeaderControls' import { PaneIcon } from './types' -import { fetchContentAndMetadata, type FileExplorerResourceMetadata } from './helper' - +import { fetchContentAndMetadata } from '../../utils/podUtils' +import { type FileExplorerResourceMetadata } from './types' @customElement('file-explorer-header') export default class FileExplorerHeader extends WebComponent { static styles = styles diff --git a/src/components/file-explorer-header/FileExplorerHeaderControls.styles.css b/src/components/file-explorer-header/FileExplorerHeaderControls.styles.css index d962f83b..8e8aadb0 100644 --- a/src/components/file-explorer-header/FileExplorerHeaderControls.styles.css +++ b/src/components/file-explorer-header/FileExplorerHeaderControls.styles.css @@ -31,6 +31,12 @@ white-space: nowrap; } + icon-lucide-share-2, + icon-lucide-pencil { + width: 16px; + height: 16px; + } + @media (max-width: 900px) { div { padding-right: 3px; @@ -42,5 +48,17 @@ justify-content: flex-start; gap: 5px; } + + .file-explorer-header-share-button, + .file-explorer-header-edit-button { + display: none; + } + + icon-lucide-ellipsis-vertical { + width: 15.36px; + height: 15.36px; + flex-shrink: 0; + aspect-ratio: 1 / 1; + } } } diff --git a/src/components/file-explorer-header/FileExplorerHeaderControls.ts b/src/components/file-explorer-header/FileExplorerHeaderControls.ts index b6668ce4..014367c4 100644 --- a/src/components/file-explorer-header/FileExplorerHeaderControls.ts +++ b/src/components/file-explorer-header/FileExplorerHeaderControls.ts @@ -1,5 +1,5 @@ import { WebComponent } from 'solid-ui' -import { customElement, property } from 'lit/decorators.js' +import { customElement, property, state } from 'lit/decorators.js' import { consume } from '@lit/context' import { html, nothing } from 'lit' import 'solid-ui/components/button' @@ -8,20 +8,50 @@ import '~icons/lucide/pencil' import styles from './FileExplorerHeaderControls.styles.css' import '../resource-actions-menu/ResourceActionsMenu' import { fileExplorerContext, type FileExplorerContext } from 'solid-ui' +import { isContainerSubject } from '../../utils/podUtils' @customElement('file-explorer-header-controls') export default class FileExplorerHeaderControls extends WebComponent { static styles = styles + private mobileMediaQuery: MediaQueryList | undefined + private readonly mobileQuery = '(max-width: 600px)' + private readonly handleMobileMediaChange = (event: MediaQueryListEvent) => { + this.isMobile = event.matches + } + @consume({ context: fileExplorerContext, subscribe: true }) accessor fileExplorerContext: FileExplorerContext = undefined as unknown as FileExplorerContext @property({ attribute: false }) - accessor menuItems: Array<{ label: string, action: (event: Event) => void }> = [] + accessor menuItems: Array<{ label: string, action: (event: Event) => void, icon?: HTMLElement }> = [] @property({ type: Boolean }) accessor canEdit: boolean = false + @state() + accessor isMobile = typeof window !== 'undefined' && typeof window.matchMedia === 'function' + ? window.matchMedia('(max-width: 600px)').matches + : false + + connectedCallback () { + super.connectedCallback() + + if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') { + return + } + + this.mobileMediaQuery = window.matchMedia(this.mobileQuery) + this.isMobile = this.mobileMediaQuery.matches + this.mobileMediaQuery.addEventListener('change', this.handleMobileMediaChange) + } + + disconnectedCallback () { + this.mobileMediaQuery?.removeEventListener('change', this.handleMobileMediaChange) + this.mobileMediaQuery = undefined + super.disconnectedCallback() + } + // TODO: Add broken then use this function to set tooltip and disable edit button /* private setEditable() { const sourcePaneState = this.sourceContext?.sourcePaneState @@ -32,10 +62,6 @@ export default class FileExplorerHeaderControls extends WebComponent { this.sourceContext?.setEditing?.() } */ - private handleEditingClick () { - this.fileExplorerContext.edit?.onEdit?.() - } - private getEditTooltip () { if (!this.fileExplorerContext.paneSupportsEditing) return 'Not Supported' if (!this.canEdit) return 'No Access' @@ -49,24 +75,36 @@ export default class FileExplorerHeaderControls extends WebComponent { } render () { + const isContainerResource = isContainerSubject(this.fileExplorerContext.store, this.fileExplorerContext.subjectUri) + return html`
${this.renderDirtyIndicator()} - - - - - - + ${!isContainerResource && !this.isMobile + ? html` + + + + + + + ` + : nothing}
` diff --git a/src/components/file-explorer-header/FileExplorerHeaderSummary.styles.css b/src/components/file-explorer-header/FileExplorerHeaderSummary.styles.css index 0fce991a..db9952b7 100644 --- a/src/components/file-explorer-header/FileExplorerHeaderSummary.styles.css +++ b/src/components/file-explorer-header/FileExplorerHeaderSummary.styles.css @@ -12,8 +12,25 @@ h1 { color: var(--solid-ui-color-gray-700, #364153); - font-size: var(--solid-ui-font-size-2xl, 1.5rem); + font-size: var(--solid-ui-font-size-xl, 1.25rem); /* while in expand; will go to 2xl when new design is complete */ font-weight: 500; + display: flex; + align-items: center; + gap: 8px; + margin: 0; + } + + .resource-info { + display: flex; + flex-direction: column; + min-width: 0; + } + + .container-info { + display: flex; + flex-direction: row; + gap: 10px; + min-width: 0; } .pane-icon { @@ -82,8 +99,50 @@ height: 0.875rem; } + .resource-date { + font-size: inherit; + } + icon-lucide-arrow-left { width: 1.125rem; height: 1.125rem; } + + @media (max-width: 600px) { + .file-explorer-header-summary { + gap: 7px; + } + + h1 { + font-size: 14px; + } + + .pane-icon { + width: 18.2px; + height: 18.2px; + flex-shrink: 0; + aspect-ratio: 1 / 1; + padding: 0; + } + + p { + font-size: 14px; + } + + .resource-date { + font-size: 10px; + } + + .public, + .private { + font-size: 9px; + } + + icon-lucide-arrow-left { + width: 15px; + height: 18px; + flex-shrink: 0; + aspect-ratio: 5 / 6; + } + } } diff --git a/src/components/file-explorer-header/FileExplorerHeaderSummary.ts b/src/components/file-explorer-header/FileExplorerHeaderSummary.ts index a02b6947..2ca785d5 100644 --- a/src/components/file-explorer-header/FileExplorerHeaderSummary.ts +++ b/src/components/file-explorer-header/FileExplorerHeaderSummary.ts @@ -8,8 +8,10 @@ import { PaneIcon } from './types' import '~icons/lucide/globe' import '~icons/lucide/lock-keyhole' import '~icons/lucide/arrow-left' +import '~icons/lucide/folder' import styles from './FileExplorerHeaderSummary.styles.css' -import { type FileExplorerResourceMetadata } from './helper' +import { getContainerItemCount, isContainerSubject } from '../../utils/podUtils' +import type { FileExplorerResourceMetadata } from './types' @customElement('file-explorer-header-summary') export default class FileExplorerHeaderSummary extends WebComponent { @@ -93,11 +95,41 @@ export default class FileExplorerHeaderSummary extends WebComponent { } } + private renderContainerResourceHeader (label: string, isPublic: boolean) { + const itemCount = getContainerItemCount(this.fileExplorerContext?.store, this.fileExplorerContext?.subjectUri) ?? 0 + return html` +
+

+ ${label} +

+

+ ${itemCount} items + ${isPublic + ? html`` + : html``} +

+
+ ` + } + + private renderResourceHeader (label: string, isPublic: boolean) { + const modified = this.formatModifiedDate(this.responseMetadata.modified) + + return html` +
+

+ ${label} +

+

${modified} ${isPublic ? html` Public` : html` Private`}

+
+ ` + } + render () { const subject = this.fileExplorerContext?.subjectUri ? sym(this.fileExplorerContext.subjectUri) : undefined const label = subject ? utils.label(subject) : '' - const modified = this.formatModifiedDate(this.responseMetadata.modified) const isPublic = this.responseMetadata.isPublic + const isContainerResource = isContainerSubject(this.fileExplorerContext?.store, this.fileExplorerContext?.subjectUri) return html`
@@ -111,10 +143,8 @@ export default class FileExplorerHeaderSummary extends WebComponent { ${this.resolvedPaneIcon ? html`` : ''} -
-

${label}

-

${modified} ${isPublic ? html` Public` : html` Private`}

-
+ ${isContainerResource ? this.renderContainerResourceHeader(label, isPublic) : this.renderResourceHeader(label, isPublic)} +
` } diff --git a/src/components/file-explorer-header/FileExplorerProvider.ts b/src/components/file-explorer-header/FileExplorerProvider.ts index 07ea4c24..b07c6997 100644 --- a/src/components/file-explorer-header/FileExplorerProvider.ts +++ b/src/components/file-explorer-header/FileExplorerProvider.ts @@ -9,6 +9,7 @@ import './FileExplorerHeader' import styles from './FileExplorerProvider.styles.css' import personIcon from '../../icons/person.svg' import friendsIcon from '../../icons/friends.svg' +import '~icons/lucide/share-2' const PERSON_ICON = personIcon const FRIENDS_ICON = friendsIcon @@ -20,7 +21,7 @@ function createFileExplorerContextValue (value: { soloPane?: boolean onBack?: () => void openPane?: (subject: NamedNode, paneName: string) => void - handleSharingClick?: () => void + handleAccessClick?: () => void paneSupportsEditing?: boolean edit?: { onEdit?: () => void @@ -35,7 +36,7 @@ function createFileExplorerContextValue (value: { soloPane: value.soloPane, onBack: value.onBack, openPane: value.openPane, - handleSharingClick: value.handleSharingClick, + handleAccessClick: value.handleAccessClick, paneSupportsEditing: value.paneSupportsEditing, edit: value.edit } @@ -125,7 +126,7 @@ export default class FileExplorerProvider extends WebComponent { soloPane: this.soloPane, onBack: this.onBack, openPane: this.openPane, - handleSharingClick: this.handleSharingClick, + handleAccessClick: this.handleAccessClick, paneSupportsEditing: false, edit: this.edit }) @@ -181,7 +182,7 @@ export default class FileExplorerProvider extends WebComponent { soloPane: this.soloPane, onBack: this.onBack, openPane: this.openPane, - handleSharingClick: this.handleSharingClick, + handleAccessClick: this.handleAccessClick, paneSupportsEditing: this.paneSupportsEditing, edit: this.edit }) @@ -228,7 +229,7 @@ export default class FileExplorerProvider extends WebComponent { changedProperties.has('soloPane') || changedProperties.has('onBack') || changedProperties.has('openPane') || - changedProperties.has('handleSharingClick') || + changedProperties.has('handleAccessClick') || changedProperties.has('pane') || changedProperties.has('isDirty') ) { diff --git a/src/components/file-explorer-header/helper.ts b/src/components/file-explorer-header/helper.ts deleted file mode 100644 index 129c30bb..00000000 --- a/src/components/file-explorer-header/helper.ts +++ /dev/null @@ -1,105 +0,0 @@ -// TODO: this code will need to be moved later -import { ACL_LINK } from 'solid-logic' -import { ns } from 'solid-ui' -import type { LiveStore, NamedNode } from 'rdflib' - -export type FileExplorerResourceMetadata = { - contentType: string | undefined - canEdit: boolean - isPublic: boolean - aclUri: string | undefined - eTag: string | undefined - modified: string | undefined -} - -function parseWacAllowHeader (headerValue: string | null | undefined) { - const permissions = new Map>() - if (!headerValue) return permissions - - for (const entry of headerValue.split(',')) { - const match = entry.trim().match(/^([A-Za-z]+)\s*=\s*"([^"]*)"$/) - if (match) { - const [, permissionGroup, accessModes] = match - const modes = accessModes.trim().split(/\s+/).filter(Boolean) - permissions.set(permissionGroup.toLowerCase(), new Set(modes.map(mode => mode.toLowerCase()))) - } - } - - return permissions -} - -function deriveAccessFlags (wacAllow: string | null | undefined) { - if (!wacAllow) { - return { canEdit: false, isPublic: false } - } - - const permissions = parseWacAllowHeader(wacAllow) - const userModes = permissions.get('user') ?? new Set() - const publicModes = permissions.get('public') ?? new Set() - - return { - canEdit: userModes.has('write'), - isPublic: publicModes.has('read') || publicModes.has('write') - } -} - -export function getResponseMetadata (store: LiveStore, subject: NamedNode, response: Response): FileExplorerResourceMetadata { - let contentType: string | undefined - let canEdit = false - let isPublic = false - let eTag: string | undefined - let modified: string | undefined - - if (response.headers && response.headers.get('content-type')) { - contentType = response.headers.get('content-type')?.split(';')[0] ?? undefined - const accessFlags = deriveAccessFlags(response.headers.get('wac-allow')) - - canEdit = accessFlags.canEdit - isPublic = accessFlags.isPublic - eTag = response.headers.get('etag') ?? undefined - modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined - } else { - const reqs = store.each( - null, - store.sym('http://www.w3.org/2007/ont/link#requestedURI'), - subject - ) - reqs.forEach((req: any) => { - const responseNode = store.any( - req as any, - store.sym('http://www.w3.org/2007/ont/link#response') - ) - if (responseNode && responseNode.termType === 'NamedNode') { - contentType = store.anyValue(responseNode as any, ns.httph('content-type')) || undefined - const wacAllow = (store.anyValue(responseNode as any, ns.httph('wac-allow')) as string | undefined) || - (store.anyValue(responseNode as any, ns.httph('WAC-Allow')) as string | undefined) - const accessFlags = deriveAccessFlags(wacAllow) - canEdit = accessFlags.canEdit - isPublic = accessFlags.isPublic - eTag = store.anyValue(responseNode as any, ns.httph('etag')) || undefined - modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined - } - }) - } - - const aclUri = store.any(subject, ACL_LINK)?.value || undefined - return { contentType, canEdit, isPublic, aclUri, eTag, modified } -} - -export async function fetchContentAndMetadata (store: LiveStore, subject: NamedNode): Promise<{ content: string, metadata: FileExplorerResourceMetadata }> { - const fetcher = store.fetcher - - const response = await fetcher.webOperation('GET', subject.uri) - const content = (response as Response & { responseText?: string }).responseText - - if (content === undefined) { - throw new Error('No text in response object!!') - } - - const metadata = getResponseMetadata(store, subject, response) - if (!metadata.contentType) { - throw new Error('No content-type available!') - } - - return { content, metadata } -} diff --git a/src/components/file-explorer-header/index.ts b/src/components/file-explorer-header/index.ts new file mode 100644 index 00000000..2140b416 --- /dev/null +++ b/src/components/file-explorer-header/index.ts @@ -0,0 +1,2 @@ +export { default as FileExplorerHeader } from './FileExplorerHeader' +export { default as FileExplorerProvider } from './FileExplorerProvider' diff --git a/src/components/file-explorer-header/types.ts b/src/components/file-explorer-header/types.ts index b3b3ecbd..826d13a8 100644 --- a/src/components/file-explorer-header/types.ts +++ b/src/components/file-explorer-header/types.ts @@ -1 +1,10 @@ export type PaneIcon = string | Promise | null | undefined + +export type FileExplorerResourceMetadata = { + contentType: string | undefined + canEdit: boolean + isPublic: boolean + aclUri: string | undefined + eTag: string | undefined + modified: string | undefined +} diff --git a/src/components/resource-actions-menu/ResourceActionsMenu.styles.css b/src/components/resource-actions-menu/ResourceActionsMenu.styles.css new file mode 100644 index 00000000..33a5392f --- /dev/null +++ b/src/components/resource-actions-menu/ResourceActionsMenu.styles.css @@ -0,0 +1,6 @@ +:host { + .ellipsisIcon { + width: 16px; + height: 16px; + } +} diff --git a/src/components/resource-actions-menu/ResourceActionsMenu.ts b/src/components/resource-actions-menu/ResourceActionsMenu.ts index 884b3004..e441e70d 100644 --- a/src/components/resource-actions-menu/ResourceActionsMenu.ts +++ b/src/components/resource-actions-menu/ResourceActionsMenu.ts @@ -1,17 +1,19 @@ -import { showDialog, utils, WebComponent } from 'solid-ui' +import { WebComponent } from 'solid-ui' import { customElement, property } from 'lit/decorators.js' -import { html } from 'lit' +import { html, nothing } from 'lit' import 'solid-ui/components/button' import 'solid-ui/components/menu' import 'solid-ui/components/menu-item' -import DeleteResourceDialog from './DeleteResourceDialog' import '~icons/lucide/ellipsis-vertical' -import '~icons/lucide/trash-2' +import '~icons/lucide/share-2' +import '~icons/lucide/pencil' import { LiveStore } from 'rdflib' -// TODO: Add Error Status section - +import styles from './ResourceActionsMenu.styles.css' +import { isContainerSubject } from '../../utils/podUtils' @customElement('resource-actions-menu') export default class ResourceActionsMenu extends WebComponent { + static styles = styles + @property({ attribute: false }) accessor store: LiveStore | undefined @@ -19,74 +21,31 @@ export default class ResourceActionsMenu extends WebComponent { accessor subjectUri: string | undefined @property({ attribute: false }) - accessor menuItems: Array<{ label: string, icon?: HTMLElement, action: (event: Event) => void }> = [] - - private confirmDelete (resourceName: string) { - return new Promise(resolve => { - showDialog(DeleteResourceDialog, { - props: { resourceName }, - onClose: (result) => resolve(result === true) - }) - }) - } - - /* private gotoParentFolder(resourceUri: string) { - const sourceContext = this.sourceContext - const outliner = sourceContext?.context?.getOutliner?.(sourceContext.context.dom) - - if (!outliner) return - - const parentFolderUri = this.getParentFolderUri(resourceUri) - ;(outliner as any).GotoSubject(sourceContext.context.session.store.sym(parentFolderUri), true, undefined, true, undefined) - } */ + accessor handleAccessClick: (() => void) | undefined = undefined - private async deleteResourceIfPresent (store: LiveStore, uri: string) { - try { - await store.fetcher.webOperation('DELETE', uri) - } catch (err: any) { - const status = err?.response?.status ?? err?.status - if (status === 404) return - throw err - } - } - - // TODO: Below is for a file only. I need to move this to a function - // that function needs to check if it's a container and if so we can do the - // recursive delete function. - // dont' forget public and private type indexes. - private async handleDelete (event: Event) { - event.preventDefault() - - if (!this.store?.fetcher || !this.subjectUri) return - - const store = this.store - const resourceNode = store.sym(this.subjectUri) + @property({ attribute: false }) + accessor handleEditingClick: (() => void) | undefined = undefined - const confirmation = await this.confirmDelete(utils.label(resourceNode)) - if (!confirmation) return + @property({ type: Boolean }) + accessor paneSupportsEditing = false - try { - await this.deleteResourceIfPresent(store, resourceNode.value) + @property({ type: Boolean }) + accessor canEdit = false - const aclUri = this.subjectUri + '.acl' - if (aclUri) { - await this.deleteResourceIfPresent(store, aclUri) - store.removeDocument(store.sym(aclUri)) - } + @property({ type: Boolean }) + accessor isMobile = false - store.removeDocument(resourceNode) - // this.gotoParentFolder(resourceNode.value) - } catch (err) { - // error('Error deleting resource:', err) - // getStatusSection()?.showError('Failed to delete resource. Check console for details.') - } - } + @property({ attribute: false }) + accessor menuItems: Array<{ label: string, icon?: unknown, action: (event: Event) => void }> = [] render () { + const isContainerResource = isContainerSubject(this.store, this.subjectUri) + const canEdit = !isContainerResource && this.isMobile && this.paneSupportsEditing && this.canEdit && !!this.handleEditingClick + const canManageAccess = !!this.handleAccessClick return html` - + ${this.menuItems.map(item => html` item.action(event)}> @@ -94,10 +53,30 @@ export default class ResourceActionsMenu extends WebComponent { ${item.label} `)} - this.handleDelete(event)}> - - Delete - + ${canEdit + ? html` + + + Edit + + ` + : nothing} + ${!isContainerResource && this.isMobile && canManageAccess + ? html` + + + Manage Access + + ` + : nothing} + ${isContainerResource && canManageAccess + ? html` + + + Manage Access + + ` + : nothing} ` } diff --git a/src/outline/manager.css b/src/outline/manager.css index 4915eed5..8e7901e2 100644 --- a/src/outline/manager.css +++ b/src/outline/manager.css @@ -80,3 +80,12 @@ width: 12px; height: 12px; } + +@media (max-width: 600px) { + .obj, + .iconTD { + font-size: 100%; + margin: 0 !important; + vertical-align: top; + } +} diff --git a/src/outline/manager.js b/src/outline/manager.js index 1207ad30..afb06da2 100644 --- a/src/outline/manager.js +++ b/src/outline/manager.js @@ -13,7 +13,7 @@ import { UserInput } from './userInput.js' import * as queryByExample from './queryByExample.js' import { loadContainerRepresentation } from '../utils/podUtils' import { isWebIdUri } from '../utils/webIdUtils' -import '../components/file-explorer-header/FileExplorerProvider' +import '../components/file-explorer-header' export default function (context) { const dom = context.dom @@ -711,10 +711,7 @@ export default function (context) { // Add the x more here const moreTR = dom.createElement('tr') const moreTD = moreTR.appendChild(dom.createElement('td')) - moreTD.setAttribute( - 'style', - 'margin: 0.2em; border: none; padding: 0; vertical-align: top;' - ) + moreTD.classList.add('obj') moreTD.setAttribute('notSelectable', 'false') if (predDups > n) { // what is this for?? @@ -790,23 +787,14 @@ export default function (context) { termWidget.construct = function (dom) { dom = dom || document const td = dom.createElement('TD') - td.setAttribute( - 'style', - 'margin: 0.2em; border: none; padding: 0; vertical-align: top;' - ) td.setAttribute('class', 'iconTD') td.setAttribute('notSelectable', 'true') - td.style.width = '0px' return td } termWidget.addIcon = function (td, icon, listener) { const iconTD = td.childNodes[1] if (!iconTD) return - let width = iconTD.style.width const img = UI.utils.AJARImage(icon.src, icon.alt, icon.tooltip, dom) - width = parseInt(width) - width = width + icon.width - iconTD.style.width = width + 'px' iconTD.appendChild(img) if (listener) { img.addEventListener('click', listener) @@ -816,10 +804,6 @@ export default function (context) { const iconTD = td.childNodes[1] let baseURI if (!iconTD) return - let width = iconTD.style.width - width = parseInt(width) - width = width - icon.width - iconTD.style.width = width + 'px' for (let x = 0; x < iconTD.childNodes.length; x++) { const elt = iconTD.childNodes[x] const eltSrc = elt.src diff --git a/src/utils/podUtils.ts b/src/utils/podUtils.ts index aa7b4aaa..81200a64 100644 --- a/src/utils/podUtils.ts +++ b/src/utils/podUtils.ts @@ -1,7 +1,40 @@ import { store } from 'solid-logic' import { ns } from 'solid-ui' -import { NamedNode, parse } from 'rdflib' +import { LiveStore, NamedNode, parse } from 'rdflib' import { isWebIdUri } from './webIdUtils' +import { ACL_LINK } from 'solid-logic' +import { FileExplorerResourceMetadata } from 'src/components/file-explorer-header/types' + +function parseWacAllowHeader (headerValue: string | null | undefined) { + const permissions = new Map>() + if (!headerValue) return permissions + + for (const entry of headerValue.split(',')) { + const match = entry.trim().match(/^([A-Za-z]+)\s*=\s*"([^"]*)"$/) + if (match) { + const [, permissionGroup, accessModes] = match + const modes = accessModes.trim().split(/\s+/).filter(Boolean) + permissions.set(permissionGroup.toLowerCase(), new Set(modes.map(mode => mode.toLowerCase()))) + } + } + + return permissions +} + +function deriveAccessFlags (wacAllow: string | null | undefined) { + if (!wacAllow) { + return { canEdit: false, isPublic: false } + } + + const permissions = parseWacAllowHeader(wacAllow) + const userModes = permissions.get('user') ?? new Set() + const publicModes = permissions.get('public') ?? new Set() + + return { + canEdit: userModes.has('write'), + isPublic: publicModes.has('read') || publicModes.has('write') + } +} export async function getPodStorages (url: NamedNode): Promise { if (isWebIdUri(url)) { @@ -56,3 +89,83 @@ export async function loadContainerRepresentation (subject) { } } } + +export function isContainerSubject (store: LiveStore | undefined, subjectUri: string | undefined): boolean { + if (!store || !subjectUri) return false + + const subject = store.sym(subjectUri) + const typeUris = store.findTypeURIs(subject) + return Boolean( + typeUris[ns.ldp('Container').uri] || + typeUris[ns.ldp('BasicContainer').uri] || + subject.uri.endsWith('/') + ) +} + +export function getContainerItemCount (store: LiveStore | undefined, subjectUri: string | undefined): number { + if (!store || !subjectUri) return 0 + + const subject = store.sym(subjectUri) + return store.each(subject, ns.ldp('contains')).length +} + +export function getResponseMetadata (store: LiveStore, subject: NamedNode, response: Response): FileExplorerResourceMetadata { + let contentType: string | undefined + let canEdit = false + let isPublic = false + let eTag: string | undefined + let modified: string | undefined + + if (response.headers && response.headers.get('content-type')) { + contentType = response.headers.get('content-type')?.split(';')[0] ?? undefined + const accessFlags = deriveAccessFlags(response.headers.get('wac-allow')) + + canEdit = accessFlags.canEdit + isPublic = accessFlags.isPublic + eTag = response.headers.get('etag') ?? undefined + modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined + } else { + const reqs = store.each( + null, + store.sym('http://www.w3.org/2007/ont/link#requestedURI'), + subject + ) + reqs.forEach((req: any) => { + const responseNode = store.any( + req as any, + store.sym('http://www.w3.org/2007/ont/link#response') + ) + if (responseNode && responseNode.termType === 'NamedNode') { + contentType = store.anyValue(responseNode as any, ns.httph('content-type')) || undefined + const wacAllow = (store.anyValue(responseNode as any, ns.httph('wac-allow')) as string | undefined) || + (store.anyValue(responseNode as any, ns.httph('WAC-Allow')) as string | undefined) + const accessFlags = deriveAccessFlags(wacAllow) + canEdit = accessFlags.canEdit + isPublic = accessFlags.isPublic + eTag = store.anyValue(responseNode as any, ns.httph('etag')) || undefined + modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined + } + }) + } + + const aclUri = store.any(subject, ACL_LINK)?.value || undefined + return { contentType, canEdit, isPublic, aclUri, eTag, modified } +} + +export async function fetchContentAndMetadata (store: LiveStore, subject: NamedNode): Promise<{ content: string, metadata: FileExplorerResourceMetadata }> { + const fetcher = store.fetcher + + const response = await fetcher.webOperation('GET', subject.uri) + const content = (response as Response & { responseText?: string }).responseText + + if (content === undefined) { + throw new Error('No text in response object!!') + } + + const metadata = getResponseMetadata(store, subject, response) + if (!metadata.contentType) { + throw new Error('No content-type available!') + } + + return { content, metadata } +}