diff --git a/ src/index.css b/ src/index.css new file mode 100644 index 0000000..0b46ea1 --- /dev/null +++ b/ src/index.css @@ -0,0 +1,76 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 10% 3.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/components.json b/components.json new file mode 100644 index 0000000..f0772a9 --- /dev/null +++ b/components.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": " src/index.css", + "baseColor": "zinc", + "cssVariables": true + }, + "aliases": { + "components": "src/universal/components", + "utils": "src/lib/utils" + } +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/antibody.graphql b/graphql/mikro_next/fragments/antibody.graphql new file mode 100644 index 0000000..9b5a152 --- /dev/null +++ b/graphql/mikro_next/fragments/antibody.graphql @@ -0,0 +1,4 @@ +fragment Antibody on Antibody { + name + epitope +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/camera.graphql b/graphql/mikro_next/fragments/camera.graphql new file mode 100644 index 0000000..8311c73 --- /dev/null +++ b/graphql/mikro_next/fragments/camera.graphql @@ -0,0 +1,10 @@ +fragment Camera on Camera { + sensorSizeX + sensorSizeY + pixelSizeX + pixelSizeY + + name + serialNumber + +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/channel.graphql b/graphql/mikro_next/fragments/channel.graphql new file mode 100644 index 0000000..5820799 --- /dev/null +++ b/graphql/mikro_next/fragments/channel.graphql @@ -0,0 +1,5 @@ +fragment Channel on Channel { + id + name + excitationWavelength +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/credentials.graphql b/graphql/mikro_next/fragments/credentials.graphql new file mode 100644 index 0000000..b2e5357 --- /dev/null +++ b/graphql/mikro_next/fragments/credentials.graphql @@ -0,0 +1,18 @@ +fragment Credentials on Credentials { + accessKey + status + secretKey + bucket + key + sessionToken + store +} + +fragment AccessCredentials on AccessCredentials { + accessKey + secretKey + bucket + key + sessionToken + path +} diff --git a/graphql/mikro_next/fragments/dataset.graphql b/graphql/mikro_next/fragments/dataset.graphql new file mode 100644 index 0000000..a058e0f --- /dev/null +++ b/graphql/mikro_next/fragments/dataset.graphql @@ -0,0 +1,31 @@ +fragment Dataset on Dataset { + id + name + description + history { + ...History + } + images { + ...ListImage + } + files { + ...ListFile + } + children { + ...ListDataset + } + isDefault + pinned + createdAt + creator { + sub + } + tags +} + +fragment ListDataset on Dataset { + id + name + description + isDefault +} diff --git a/graphql/mikro_next/fragments/era.graphql b/graphql/mikro_next/fragments/era.graphql new file mode 100644 index 0000000..c77785d --- /dev/null +++ b/graphql/mikro_next/fragments/era.graphql @@ -0,0 +1,5 @@ +fragment Era on Era { + id + begin + name +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/file.graphql b/graphql/mikro_next/fragments/file.graphql new file mode 100644 index 0000000..085ed2a --- /dev/null +++ b/graphql/mikro_next/fragments/file.graphql @@ -0,0 +1,15 @@ +fragment File on File { + origins { + id + } + id + name + store { + ...BigFileStore + } +} + +fragment ListFile on File { + id + name +} diff --git a/graphql/mikro_next/fragments/fluorophore.graphql b/graphql/mikro_next/fragments/fluorophore.graphql new file mode 100644 index 0000000..6b1608d --- /dev/null +++ b/graphql/mikro_next/fragments/fluorophore.graphql @@ -0,0 +1,5 @@ +fragment Fluorophore on Fluorophore { + name + emissionWavelength + excitationWavelength +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/history.graphql b/graphql/mikro_next/fragments/history.graphql new file mode 100644 index 0000000..afcaacd --- /dev/null +++ b/graphql/mikro_next/fragments/history.graphql @@ -0,0 +1,6 @@ +fragment History on History { + id + during + kind + date +} diff --git a/graphql/mikro_next/fragments/image.graphql b/graphql/mikro_next/fragments/image.graphql new file mode 100644 index 0000000..c4cc10f --- /dev/null +++ b/graphql/mikro_next/fragments/image.graphql @@ -0,0 +1,55 @@ +fragment Image on Image { + origins { + id + } + id + name + store { + ...ZarrStore + } + views { + ...ChannelView + ...TransformationView + ...LabelView + ...TimepointView + ...OpticsView + } + pinned + renders { + ...Snapshot + ...Video + } + dataset { + name + id + } + createdAt + history(pagination: { limit: 3 }) { + ...History + } + creator { + sub + } + tags + metrics { + ...ImageMetric + } + roiOrigins { + ...ListROI + } + fileOrigins { + ...ListFile + } +} + +fragment ListImage on Image { + latestSnapshot { + id + store { + key + presignedUrl + } + } + id + name +} diff --git a/graphql/mikro_next/fragments/instrument.graphql b/graphql/mikro_next/fragments/instrument.graphql new file mode 100644 index 0000000..b3bde57 --- /dev/null +++ b/graphql/mikro_next/fragments/instrument.graphql @@ -0,0 +1,6 @@ +fragment Instrument on Instrument { + model + name + serialNumber + +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/metric.graphql b/graphql/mikro_next/fragments/metric.graphql new file mode 100644 index 0000000..347d4e2 --- /dev/null +++ b/graphql/mikro_next/fragments/metric.graphql @@ -0,0 +1,8 @@ +fragment ImageIntMetric on ImageIntMetric { + id + value +} + +fragment ImageMetric on ImageMetric { + ...ImageIntMetric +} diff --git a/graphql/mikro_next/fragments/objective.graphql b/graphql/mikro_next/fragments/objective.graphql new file mode 100644 index 0000000..01978ad --- /dev/null +++ b/graphql/mikro_next/fragments/objective.graphql @@ -0,0 +1,6 @@ +fragment Objective on Objective { + na + name + serialNumber + +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/roi.graphql b/graphql/mikro_next/fragments/roi.graphql new file mode 100644 index 0000000..23dcb0d --- /dev/null +++ b/graphql/mikro_next/fragments/roi.graphql @@ -0,0 +1,7 @@ +fragment ListROI on ROI { + id + image { + id + name + } +} diff --git a/graphql/mikro_next/fragments/snapshot.graphql b/graphql/mikro_next/fragments/snapshot.graphql new file mode 100644 index 0000000..73b1dc5 --- /dev/null +++ b/graphql/mikro_next/fragments/snapshot.graphql @@ -0,0 +1,7 @@ +fragment Snapshot on Snapshot { + id + store { + key + presignedUrl + } +} \ No newline at end of file diff --git a/graphql/mikro_next/fragments/stage.graphql b/graphql/mikro_next/fragments/stage.graphql new file mode 100644 index 0000000..6dcb2e7 --- /dev/null +++ b/graphql/mikro_next/fragments/stage.graphql @@ -0,0 +1,13 @@ +fragment Stage on Stage { + id + views { + ...TransformationView + } + pinned + name +} + +fragment ListStage on Stage { + id + name +} diff --git a/graphql/mikro_next/fragments/store.graphql b/graphql/mikro_next/fragments/store.graphql new file mode 100644 index 0000000..cd9b840 --- /dev/null +++ b/graphql/mikro_next/fragments/store.graphql @@ -0,0 +1,22 @@ +fragment ZarrStore on ZarrStore { + id + key + bucket + path + shape + dtype +} + +fragment ParquetStore on ParquetStore { + id + key + bucket + path +} + +fragment BigFileStore on BigFileStore { + id + key + bucket + path +} diff --git a/graphql/mikro_next/fragments/table.graphql b/graphql/mikro_next/fragments/table.graphql new file mode 100644 index 0000000..1a0584c --- /dev/null +++ b/graphql/mikro_next/fragments/table.graphql @@ -0,0 +1,10 @@ +fragment Table on Table { + origins { + id + } + id + name + store { + ...ParquetStore + } +} diff --git a/graphql/mikro_next/fragments/video.graphql b/graphql/mikro_next/fragments/video.graphql new file mode 100644 index 0000000..2e0bcdc --- /dev/null +++ b/graphql/mikro_next/fragments/video.graphql @@ -0,0 +1,7 @@ +fragment Video on Video { + id + store { + key + presignedUrl + } +} diff --git a/graphql/mikro_next/fragments/views.graphql b/graphql/mikro_next/fragments/views.graphql new file mode 100644 index 0000000..c43e8c5 --- /dev/null +++ b/graphql/mikro_next/fragments/views.graphql @@ -0,0 +1,66 @@ +fragment View on View { + zMin + zMax +} + +fragment ChannelView on ChannelView { + ...View + id + channel { + ...Channel + } +} + +fragment TransformationView on TransformationView { + ...View + id + kind + matrix + stage { + id + } +} + +fragment TimepointView on TimepointView { + ...View + id + msSinceStart + indexSinceStart + era { + ...Era + } +} + +fragment OpticsView on OpticsView { + ...View + id + objective { + id + name + serialNumber + } + camera { + id + name + serialNumber + } + instrument { + id + name + serialNumber + } +} + +fragment LabelView on LabelView { + ...View + id + fluorophore { + ...Fluorophore + } + primaryAntibody { + ...Antibody + } + secondaryAntibody { + ...Antibody + } +} diff --git a/graphql/mikro_next/mutations/antibody.graphql b/graphql/mikro_next/mutations/antibody.graphql new file mode 100644 index 0000000..686137a --- /dev/null +++ b/graphql/mikro_next/mutations/antibody.graphql @@ -0,0 +1,14 @@ +mutation CreateAntibody($name: String!, $epitope: String ) { + createAntibody(input: {name: $name, epitope: $epitope}) { + id + name + } +} + +mutation EnsureAntibody($name: String!, $epitope: String ) { + ensureAntibody(input: {name: $name, epitope: $epitope}) { + id + name + } +} + diff --git a/graphql/mikro_next/mutations/camera.graphql b/graphql/mikro_next/mutations/camera.graphql new file mode 100644 index 0000000..8bb4f41 --- /dev/null +++ b/graphql/mikro_next/mutations/camera.graphql @@ -0,0 +1,35 @@ +mutation CreateCamera($serialNumber: String!, $name: String, $pixelSizeX: Micrometers, $pixelSizeY: Micrometers, $sensorSizeX: Int, $sensorSizeY: Int,) { + createCamera(input: { + name: $name, + pixelSizeX: $pixelSizeX, + serialNumber: $serialNumber, + pixelSizeY: $pixelSizeY, + sensorSizeX: $sensorSizeX, + sensorSizeY: $sensorSizeY, + + + + + }) { + id + name + } +} + +mutation EnsureCamera($serialNumber: String!, $name: String, $pixelSizeX: Micrometers, $pixelSizeY: Micrometers, $sensorSizeX: Int, $sensorSizeY: Int,) { + ensureCamera(input: { + name: $name, + pixelSizeX: $pixelSizeX, + serialNumber: $serialNumber, + pixelSizeY: $pixelSizeY, + sensorSizeX: $sensorSizeX, + sensorSizeY: $sensorSizeY, + + + + + }) { + id + name + } +} \ No newline at end of file diff --git a/graphql/mikro_next/mutations/channel.graphql b/graphql/mikro_next/mutations/channel.graphql new file mode 100644 index 0000000..38a15dd --- /dev/null +++ b/graphql/mikro_next/mutations/channel.graphql @@ -0,0 +1,16 @@ +mutation CreateChannel($name: String!) { + createChannel(input: {name: $name}) { + id + name + } +} + +mutation EnsureChannel($name: String!){ + ensureChannel(input: { + name: $name + }) { + id + name + + } +} \ No newline at end of file diff --git a/graphql/mikro_next/mutations/dataset.graphql b/graphql/mikro_next/mutations/dataset.graphql new file mode 100644 index 0000000..c71b250 --- /dev/null +++ b/graphql/mikro_next/mutations/dataset.graphql @@ -0,0 +1,63 @@ +mutation CreateDataset($name: String!) { + createDataset(input: { name: $name }) { + id + name + } +} + +mutation UpdateDataset($id: ID!, $name: String!) { + updateDataset(input: { id: $id, name: $name }) { + id + name + } +} + +mutation PinDataset($id: ID!, $pin: Boolean!) { + pinDataset(input: { id: $id, pin: $pin }) { + ...Dataset + } +} + +mutation PutDatasetsInDataset($selfs: [ID!]!, $other: ID!) { + putDatasetsInDataset(input: { selfs: $selfs, other: $other }) { + ...Dataset + } +} + +mutation ReleaseDatasetsFromDataset($selfs: [ID!]!, $other: ID!) { + releaseDatasetsFromDataset(input: { selfs: $selfs, other: $other }) { + ...Dataset + } +} + +mutation PutImagesInDataset($selfs: [ID!]!, $other: ID!) { + putImagesInDataset(input: { selfs: $selfs, other: $other }) { + ...Dataset + } +} + +mutation ReleaseImagesFromDataset($selfs: [ID!]!, $other: ID!) { + releaseImagesFromDataset(input: { selfs: $selfs, other: $other }) { + ...Dataset + } +} + +mutation PutFilesInDataset($selfs: [ID!]!, $other: ID!) { + putFilesInDataset(input: { selfs: $selfs, other: $other }) { + ...Dataset + } +} + +mutation ReleaseFilesFromDataset($selfs: [ID!]!, $other: ID!) { + releaseFilesFromDataset(input: { selfs: $selfs, other: $other }) { + ...Dataset + } +} + +mutation RevertDataset($dataset: ID!, $history: ID!) { + revertDataset(input: { id: $dataset, historyId: $history }) { + id + name + description + } +} diff --git a/graphql/mikro_next/mutations/era.graphql b/graphql/mikro_next/mutations/era.graphql new file mode 100644 index 0000000..0c116ad --- /dev/null +++ b/graphql/mikro_next/mutations/era.graphql @@ -0,0 +1,6 @@ +mutation CreateEra($name: String!, $begin: DateTime) { + createEra(input: {name: $name, begin: $begin}) { + id + begin + } +} \ No newline at end of file diff --git a/graphql/mikro_next/mutations/file.graphql b/graphql/mikro_next/mutations/file.graphql new file mode 100644 index 0000000..ed4ec66 --- /dev/null +++ b/graphql/mikro_next/mutations/file.graphql @@ -0,0 +1,24 @@ +mutation from_file_like( + $file: FileLike! + $name: String! + $origins: [ID!] + $dataset: ID +) { + fromFileLike( + input: { file: $file, name: $name, origins: $origins, dataset: $dataset } + ) { + ...File + } +} + +mutation RequestFileUpload($key: String!, $datalayer: String!) { + requestFileUpload(input: { key: $key, datalayer: $datalayer }) { + ...Credentials + } +} + +mutation RequestFileAccess($store: ID!, $duration: Int) { + requestFileAccess(input: { store: $store, duration: $duration }) { + ...AccessCredentials + } +} diff --git a/graphql/mikro_next/mutations/fluorophore.graphql b/graphql/mikro_next/mutations/fluorophore.graphql new file mode 100644 index 0000000..e3b6a96 --- /dev/null +++ b/graphql/mikro_next/mutations/fluorophore.graphql @@ -0,0 +1,18 @@ +mutation CreateFluorophore($name: String!, $excitationWavelength: Micrometers, $emissionWavelength: Micrometers) { + createFluorophore(input: {name: $name, excitationWavelength: $excitationWavelength, emissionWavelength: $emissionWavelength}) { + id + name + } +} + +mutation EnsureFluorophore($name: String!, $excitationWavelength: Micrometers, $emissionWavelength: Micrometers){ + ensureFluorophore(input: { + name: $name + excitationWavelength: $excitationWavelength + emissionWavelength: $emissionWavelength + }) { + id + name + + } +} \ No newline at end of file diff --git a/graphql/mikro_next/mutations/image.graphql b/graphql/mikro_next/mutations/image.graphql new file mode 100644 index 0000000..96206d7 --- /dev/null +++ b/graphql/mikro_next/mutations/image.graphql @@ -0,0 +1,43 @@ +mutation from_array_like( + $array: ArrayLike! + $name: String! + $origins: [ID!] + $channelViews: [PartialChannelViewInput!] + $transformationViews: [PartialTransformationViewInput!] + $labelViews: [PartialLabelViewInput!] + $timepointViews: [PartialTimepointViewInput!] + $opticsViews: [PartialOpticsViewInput!] +) { + fromArrayLike( + input: { + array: $array + name: $name + origins: $origins + channelViews: $channelViews + transformationViews: $transformationViews + labelViews: $labelViews + timepointViews: $timepointViews + opticsViews: $opticsViews + } + ) { + ...Image + } +} + +mutation RequestUpload($key: String!, $datalayer: String!) { + requestUpload(input: { key: $key, datalayer: $datalayer }) { + ...Credentials + } +} + +mutation RequestAccess($store: ID!, $duration: Int) { + requestAccess(input: { store: $store, duration: $duration }) { + ...AccessCredentials + } +} + +mutation PinImage($id: ID!, $pin: Boolean!) { + pinImage(input: { id: $id, pin: $pin }) { + ...Image + } +} diff --git a/graphql/mikro_next/mutations/instrument.graphql b/graphql/mikro_next/mutations/instrument.graphql new file mode 100644 index 0000000..c1cd43f --- /dev/null +++ b/graphql/mikro_next/mutations/instrument.graphql @@ -0,0 +1,13 @@ +mutation CreateInstrument($serialNumber: String!, $name: String, $model: String) { + createInstrument(input: {name: $name, model: $model, serialNumber: $serialNumber}) { + id + name + } +} + +mutation EnsureInstrument($serialNumber: String!, $name: String, $model: String) { + ensureInstrument(input: {name: $name, model: $model, serialNumber: $serialNumber}) { + id + name + } +} diff --git a/graphql/mikro_next/mutations/objective.graphql b/graphql/mikro_next/mutations/objective.graphql new file mode 100644 index 0000000..b9a0679 --- /dev/null +++ b/graphql/mikro_next/mutations/objective.graphql @@ -0,0 +1,13 @@ +mutation CreateObjective($serialNumber: String!, $name: String, $na: Float, $magnification: Float) { + createObjective(input: {name: $name, na: $na, serialNumber: $serialNumber, magnification: $magnification}) { + id + name + } +} + +mutation EnsureObjective($serialNumber: String!, $name: String, $na: Float, $magnification: Float) { + ensureObjective(input: {name: $name, na: $na, serialNumber: $serialNumber, magnification: $magnification}) { + id + name + } +} diff --git a/graphql/mikro_next/mutations/snapshot.graphql b/graphql/mikro_next/mutations/snapshot.graphql new file mode 100644 index 0000000..31fc878 --- /dev/null +++ b/graphql/mikro_next/mutations/snapshot.graphql @@ -0,0 +1,5 @@ +mutation CreateSnapshot($image: ID!, $file: Upload!) { + createSnapshot(input: { file: $file , image: $image}) { + ...Snapshot + } +} diff --git a/graphql/mikro_next/mutations/stage.graphql b/graphql/mikro_next/mutations/stage.graphql new file mode 100644 index 0000000..83006dd --- /dev/null +++ b/graphql/mikro_next/mutations/stage.graphql @@ -0,0 +1,12 @@ +mutation CreateStage($name: String!) { + createStage(input: { name: $name }) { + id + name + } +} + +mutation PinStage($id: ID!, $pin: Boolean!) { + pinStage(input: { id: $id, pin: $pin }) { + ...Stage + } +} diff --git a/graphql/mikro_next/mutations/table.graphql b/graphql/mikro_next/mutations/table.graphql new file mode 100644 index 0000000..a7bc178 --- /dev/null +++ b/graphql/mikro_next/mutations/table.graphql @@ -0,0 +1,29 @@ +mutation from_parquet_like( + $dataframe: ParquetLike! + $name: String! + $origins: [ID!] + $dataset: ID +) { + fromParquetLike( + input: { + dataframe: $dataframe + name: $name + origins: $origins + dataset: $dataset + } + ) { + ...Table + } +} + +mutation RequestTableUpload($key: String!, $datalayer: String!) { + requestTableUpload(input: { key: $key, datalayer: $datalayer }) { + ...Credentials + } +} + +mutation RequestTableAccess($store: ID!, $duration: Int) { + requestTableAccess(input: { store: $store, duration: $duration }) { + ...AccessCredentials + } +} diff --git a/graphql/mikro_next/mutations/viewcollection.graphql b/graphql/mikro_next/mutations/viewcollection.graphql new file mode 100644 index 0000000..d171cb6 --- /dev/null +++ b/graphql/mikro_next/mutations/viewcollection.graphql @@ -0,0 +1,6 @@ +mutation CreateViewCollection($name: String!) { + createViewCollection(input: {name: $name}) { + id + name + } +} \ No newline at end of file diff --git a/graphql/mikro_next/queries/camera.graphql b/graphql/mikro_next/queries/camera.graphql new file mode 100644 index 0000000..d962166 --- /dev/null +++ b/graphql/mikro_next/queries/camera.graphql @@ -0,0 +1,5 @@ +query GetCamera($id: ID!) { + camera(id: $id) { + ...Camera + } +} \ No newline at end of file diff --git a/graphql/mikro_next/queries/channel.graphql b/graphql/mikro_next/queries/channel.graphql new file mode 100644 index 0000000..e69de29 diff --git a/graphql/mikro_next/queries/dataset.graphql b/graphql/mikro_next/queries/dataset.graphql new file mode 100644 index 0000000..95cb4e9 --- /dev/null +++ b/graphql/mikro_next/queries/dataset.graphql @@ -0,0 +1,11 @@ +query GetDataset($id: ID!) { + dataset(id: $id) { + ...Dataset + } +} + +query GetDatasets($filters: DatasetFilter, $pagination: OffsetPaginationInput) { + datasets(filters: $filters, pagination: $pagination) { + ...ListDataset + } +} diff --git a/graphql/mikro_next/queries/file.graphql b/graphql/mikro_next/queries/file.graphql new file mode 100644 index 0000000..f34fb64 --- /dev/null +++ b/graphql/mikro_next/queries/file.graphql @@ -0,0 +1,5 @@ +query GetFile($id: ID!) { + file(id: $id) { + ...File + } +} diff --git a/graphql/mikro_next/queries/hallo.graphql b/graphql/mikro_next/queries/hallo.graphql new file mode 100644 index 0000000..cb1c61c --- /dev/null +++ b/graphql/mikro_next/queries/hallo.graphql @@ -0,0 +1,6 @@ + +query Images{ + images { + id + } +} \ No newline at end of file diff --git a/graphql/mikro_next/queries/image copy.graphql b/graphql/mikro_next/queries/image copy.graphql new file mode 100644 index 0000000..62b7080 --- /dev/null +++ b/graphql/mikro_next/queries/image copy.graphql @@ -0,0 +1,11 @@ +query GetImage($id: ID!) { + image(id: $id) { + ...Image + } +} + +query GetImages($filters: ImageFilter, $pagination: OffsetPaginationInput) { + images(filters: $filters, pagination: $pagination) { + ...ListImage + } +} diff --git a/graphql/mikro_next/queries/image.graphql b/graphql/mikro_next/queries/image.graphql new file mode 100644 index 0000000..62b7080 --- /dev/null +++ b/graphql/mikro_next/queries/image.graphql @@ -0,0 +1,11 @@ +query GetImage($id: ID!) { + image(id: $id) { + ...Image + } +} + +query GetImages($filters: ImageFilter, $pagination: OffsetPaginationInput) { + images(filters: $filters, pagination: $pagination) { + ...ListImage + } +} diff --git a/graphql/mikro_next/queries/instrument.graphql b/graphql/mikro_next/queries/instrument.graphql new file mode 100644 index 0000000..44d43e4 --- /dev/null +++ b/graphql/mikro_next/queries/instrument.graphql @@ -0,0 +1,5 @@ +query GetInstrument($id: ID!) { + instrument(id: $id) { + ...Instrument + } +} diff --git a/graphql/mikro_next/queries/objective.graphql b/graphql/mikro_next/queries/objective.graphql new file mode 100644 index 0000000..168f6fa --- /dev/null +++ b/graphql/mikro_next/queries/objective.graphql @@ -0,0 +1,5 @@ +query GetObjective($id: ID!) { + objective(id: $id) { + ...Objective + } +} \ No newline at end of file diff --git a/graphql/mikro_next/queries/stage.graphql b/graphql/mikro_next/queries/stage.graphql new file mode 100644 index 0000000..00fb832 --- /dev/null +++ b/graphql/mikro_next/queries/stage.graphql @@ -0,0 +1,11 @@ +query GetStage($id: ID!) { + stage(id: $id) { + ...Stage + } +} + +query GetStages($filters: StageFilter, $pagination: OffsetPaginationInput) { + stages(filters: $filters, pagination: $pagination) { + ...ListStage + } +} diff --git a/graphql/mikro_next/queries/table.graphql b/graphql/mikro_next/queries/table.graphql new file mode 100644 index 0000000..06d96e1 --- /dev/null +++ b/graphql/mikro_next/queries/table.graphql @@ -0,0 +1,5 @@ +query GetTable($id: ID!) { + table(id: $id) { + ...Table + } +} diff --git a/graphql/port/fragments/container.graphql b/graphql/port/fragments/container.graphql deleted file mode 100644 index 9858aa7..0000000 --- a/graphql/port/fragments/container.graphql +++ /dev/null @@ -1,26 +0,0 @@ -fragment DetailContainer on Container { - id - name - image { - ...DetailImage - } - logs - labels - status - whale { - ...DetailWhale - } -} - -fragment ListContainer on Container { - id - name - image { - ...DetailImage - } - labels - status - whale { - ...DetailWhale - } -} diff --git a/graphql/port/fragments/deployment.graphql b/graphql/port/fragments/deployment.graphql deleted file mode 100644 index 52dd42c..0000000 --- a/graphql/port/fragments/deployment.graphql +++ /dev/null @@ -1,24 +0,0 @@ -fragment DetailDeployment on Deployment { - id - identifier - version - scopes - image - requirements - command - logo - originalLogo -} - -fragment ListDeployment on Deployment { - id - identifier - version - scopes - image - whales { - id - } - command - logo -} diff --git a/graphql/port/fragments/image.graphql b/graphql/port/fragments/image.graphql deleted file mode 100644 index a484876..0000000 --- a/graphql/port/fragments/image.graphql +++ /dev/null @@ -1,3 +0,0 @@ -fragment DetailImage on Image { - tags -} diff --git a/graphql/port/fragments/network.graphql b/graphql/port/fragments/network.graphql deleted file mode 100644 index d5614ff..0000000 --- a/graphql/port/fragments/network.graphql +++ /dev/null @@ -1,4 +0,0 @@ -fragment DetailNetwork on Network { - name - id -} diff --git a/graphql/port/fragments/repo.graphql b/graphql/port/fragments/repo.graphql deleted file mode 100644 index c9a6192..0000000 --- a/graphql/port/fragments/repo.graphql +++ /dev/null @@ -1,17 +0,0 @@ -fragment DetailGithubRepo on GithubRepo { - id - user - repo - branch - deployments { - ...ListDeployment - } - readme -} - -fragment ListGithubRepo on GithubRepo { - id - user - repo - branch -} diff --git a/graphql/port/fragments/whale.graphql b/graphql/port/fragments/whale.graphql deleted file mode 100644 index 78e1f73..0000000 --- a/graphql/port/fragments/whale.graphql +++ /dev/null @@ -1,38 +0,0 @@ -fragment DetailWhale on Whale { - id - deployment { - ...DetailDeployment - } - pulled - latestPull - token - containers { - id - name - image { - ...DetailImage - } - logs - labels - status - } -} - -fragment ListWhale on Whale { - id - createdAt - deployment { - ...ListDeployment - } - clientId - pulled - token - latestPull - latestEvent { - whale - pull { - status - progress - } - } -} diff --git a/graphql/port/mutations/container.graphql b/graphql/port/mutations/container.graphql deleted file mode 100644 index ca59cee..0000000 --- a/graphql/port/mutations/container.graphql +++ /dev/null @@ -1,23 +0,0 @@ -mutation StopContainer($id: ID!) { - stopContainer(id: $id) { - id - name - status - } -} - -mutation RemoveContainer($id: ID!) { - removeContainer(id: $id) { - id - name - status - } -} - -mutation RestartContainer($id: ID!) { - restartContainer(id: $id) { - id - name - status - } -} diff --git a/graphql/port/mutations/repo.graphql b/graphql/port/mutations/repo.graphql deleted file mode 100644 index 0345e6b..0000000 --- a/graphql/port/mutations/repo.graphql +++ /dev/null @@ -1,19 +0,0 @@ -mutation DeleteGithubRepo($id: ID!) { - deleteGithubRepo(id: $id) { - id - } -} - -mutation CreateGithubRepo($repo: String!, $user: String!, $branch: String!) { - createGithubRepo(repo: $repo, user: $user, branch: $branch) { - ...ListGithubRepo - } -} - -mutation ScanRepo($id: ID!) { - scanRepo(id: $id) { - id - identifier - version - } -} diff --git a/graphql/port/mutations/whale.graphql b/graphql/port/mutations/whale.graphql deleted file mode 100644 index 5562c41..0000000 --- a/graphql/port/mutations/whale.graphql +++ /dev/null @@ -1,29 +0,0 @@ -mutation RunWhale($id: ID!, $instance: String) { - runWhale(id: $id, instance: $instance) { - ...DetailWhale - } -} - -mutation DeleteWhale($id: ID!) { - deleteWhale(id: $id) { - id - } -} - -mutation PullWhale($id: ID!) { - pullWhale(id: $id) { - id - } -} - -mutation PurgeWhale($id: ID!) { - purgeWhale(id: $id) { - ...DetailWhale - } -} - -mutation CreateWhale($deployment: ID!, $clientId: String!, $token: String!) { - createWhale(deployment: $deployment, clientId: $clientId, token: $token) { - ...DetailWhale - } -} diff --git a/graphql/port/queries/container.graphql b/graphql/port/queries/container.graphql deleted file mode 100644 index 7a267ac..0000000 --- a/graphql/port/queries/container.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query Containers($status: [ContainerStatus]) { - containers(status: $status) { - ...ListContainer - } -} - -query DetailContainer($id: ID!) { - container(id: $id) { - ...DetailContainer - } -} diff --git a/graphql/port/queries/deployments.graphql b/graphql/port/queries/deployments.graphql deleted file mode 100644 index abc3612..0000000 --- a/graphql/port/queries/deployments.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query Deployments($limit: Int, $offset: Int) { - deployments(limit: $limit, offset: $offset) { - ...ListDeployment - } -} - -query DetailDeployment($id: ID!) { - deployment(id: $id) { - ...DetailDeployment - } -} diff --git a/graphql/port/queries/repo.graphql b/graphql/port/queries/repo.graphql deleted file mode 100644 index 86708fa..0000000 --- a/graphql/port/queries/repo.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query GithubRepos($limit: Int, $offset: Int) { - githubRepos(limit: $limit, offset: $offset) { - ...ListGithubRepo - } -} - -query DetailGithubRepo($id: ID!) { - githubRepo(id: $id) { - ...DetailGithubRepo - } -} diff --git a/graphql/port/queries/search.graphql b/graphql/port/queries/search.graphql deleted file mode 100644 index f51f901..0000000 --- a/graphql/port/queries/search.graphql +++ /dev/null @@ -1,9 +0,0 @@ -query PortGlobalSearch($search: String) { - containers(search: $search) { - ...ListContainer - } - - whales(search: $search) { - ...ListWhale - } -} diff --git a/graphql/port/queries/whale.graphql b/graphql/port/queries/whale.graphql deleted file mode 100644 index f118933..0000000 --- a/graphql/port/queries/whale.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query DetailWhale($id: ID!) { - whale(id: $id) { - ...DetailWhale - } -} - -query Whales($limit: Int, $offset: Int) { - whales(limit: $limit, offset: $offset) { - ...ListWhale - } -} diff --git a/graphql/port/subscriptions/whale.graphql b/graphql/port/subscriptions/whale.graphql deleted file mode 100644 index ad90f27..0000000 --- a/graphql/port/subscriptions/whale.graphql +++ /dev/null @@ -1,12 +0,0 @@ -subscription MyWhalesUpdate { - whalesEvent { - whale - pull { - status - progress - } - up { - container - } - } -} diff --git a/graphql/rekuest/fragments/asssignation.graphql b/graphql/rekuest/fragments/asssignation.graphql index e94a2ff..346b3de 100644 --- a/graphql/rekuest/fragments/asssignation.graphql +++ b/graphql/rekuest/fragments/asssignation.graphql @@ -1,10 +1,16 @@ -fragment DetailAssignation on Assignation { - status +fragment PostmanAssignation on Assignation { id + status + statusmessage args kwargs reference progress + returns +} + +fragment DetailAssignation on Assignation { + ...PostmanAssignation parent { id reservation { @@ -15,8 +21,6 @@ fragment DetailAssignation on Assignation { } } } - - statusmessage provision { status id @@ -88,13 +92,7 @@ fragment DetailAssignation on Assignation { } fragment ListAssignation on Assignation { - status - id - args - kwargs - reference - createdAt - progress + ...PostmanAssignation reservation { id title diff --git a/graphql/rekuest/fragments/ports.graphql b/graphql/rekuest/fragments/ports.graphql index bb263b8..e503dba 100644 --- a/graphql/rekuest/fragments/ports.graphql +++ b/graphql/rekuest/fragments/ports.graphql @@ -39,6 +39,7 @@ fragment ChoiceWidget on ChoiceWidget { choices { value label + description } } @@ -104,7 +105,6 @@ fragment Dependency on Dependency { key condition value - } fragment Effect on Effect { @@ -181,6 +181,7 @@ fragment ChoiceReturnWidget on ChoiceReturnWidget { choices { label value + description } } diff --git a/graphql/rekuest/fragments/provision.graphql b/graphql/rekuest/fragments/provision.graphql index c27366e..e6598f5 100644 --- a/graphql/rekuest/fragments/provision.graphql +++ b/graphql/rekuest/fragments/provision.graphql @@ -1,8 +1,12 @@ -fragment DetailProvision on Provision { +fragment PostmanProvision on Provision { statusmessage status id reference +} + +fragment DetailProvision on Provision { + ...PostmanProvision params { autoUnprovide } @@ -74,9 +78,7 @@ fragment DetailProvision on Provision { } fragment ListProvision on Provision { - status - id - reference + ...PostmanProvision template { id interface diff --git a/graphql/rekuest/fragments/reservation.graphql b/graphql/rekuest/fragments/reservation.graphql index f922b52..5672342 100644 --- a/graphql/rekuest/fragments/reservation.graphql +++ b/graphql/rekuest/fragments/reservation.graphql @@ -1,9 +1,13 @@ -fragment DetailReservation on Reservation { +fragment PostmanReservation on Reservation { title status id reference statusmessage +} + +fragment DetailReservation on Reservation { + ...PostmanReservation params { autoProvide autoUnprovide @@ -125,6 +129,7 @@ fragment NodeReservation on Reservation { } fragment ListReservation on Reservation { + ...PostmanReservation title status statusmessage diff --git a/graphql/rekuest/fragments/template.graphql b/graphql/rekuest/fragments/template.graphql index e3488c4..f717c28 100644 --- a/graphql/rekuest/fragments/template.graphql +++ b/graphql/rekuest/fragments/template.graphql @@ -37,6 +37,7 @@ fragment DetailTemplate on Template { fragment ReservableTemplate on Template { id name + interface node { scope id diff --git a/graphql/rekuest/mutations/postman/ack.graphql b/graphql/rekuest/mutations/postman/ack.graphql index 53725ad..778c640 100644 --- a/graphql/rekuest/mutations/postman/ack.graphql +++ b/graphql/rekuest/mutations/postman/ack.graphql @@ -1,5 +1,5 @@ mutation Acknowledge($assignation: ID!) { ack(assignation: $assignation) { - reference + ...PostmanAssignation } } diff --git a/graphql/rekuest/mutations/postman/assign.graphql b/graphql/rekuest/mutations/postman/assign.graphql index 22b861c..5960e53 100644 --- a/graphql/rekuest/mutations/postman/assign.graphql +++ b/graphql/rekuest/mutations/postman/assign.graphql @@ -1,5 +1,5 @@ mutation Assign($reservation: ID!, $args: [AnyInput]!) { assign(reservation: $reservation, args: $args) { - ...DetailAssignation + ...PostmanAssignation } } diff --git a/graphql/rekuest/mutations/postman/provide.graphql b/graphql/rekuest/mutations/postman/provide.graphql index c51c71c..d5115e5 100644 --- a/graphql/rekuest/mutations/postman/provide.graphql +++ b/graphql/rekuest/mutations/postman/provide.graphql @@ -1,6 +1,5 @@ mutation Provide($template: ID!) { provide(template: $template) { - id - status + ...PostmanProvision } } diff --git a/graphql/rekuest/mutations/postman/reserve.graphql b/graphql/rekuest/mutations/postman/reserve.graphql index d715eab..6cdc721 100644 --- a/graphql/rekuest/mutations/postman/reserve.graphql +++ b/graphql/rekuest/mutations/postman/reserve.graphql @@ -1,6 +1,8 @@ mutation Reserve( + $instanceId: ID! $node: ID $hash: String + $template: ID $params: ReserveParamsInput $binds: ReserveBindsInput $title: String @@ -8,7 +10,9 @@ mutation Reserve( $allowAutoRequest: Boolean ) { reserve( + instanceId: $instanceId node: $node + template: $template hash: $hash params: $params binds: $binds @@ -16,7 +20,6 @@ mutation Reserve( allowAutoRequest: $allowAutoRequest imitate: $imitate ) { - id - reference + ...PostmanReservation } } diff --git a/graphql/rekuest/mutations/postman/unassign.graphql b/graphql/rekuest/mutations/postman/unassign.graphql index 980eac8..530644a 100644 --- a/graphql/rekuest/mutations/postman/unassign.graphql +++ b/graphql/rekuest/mutations/postman/unassign.graphql @@ -1,5 +1,5 @@ mutation Unassign($assignation: ID!) { - unassign(assignation: $assignation) { - reference - } + unassign(assignation: $assignation) { + id + } } diff --git a/graphql/rekuest/queries/assignation.graphql b/graphql/rekuest/queries/assignation.graphql index 9febdaf..b4b2bb5 100644 --- a/graphql/rekuest/queries/assignation.graphql +++ b/graphql/rekuest/queries/assignation.graphql @@ -30,8 +30,8 @@ query NodeAssignations( } } -query Requests { - requests(exclude: [DONE, CRITICAL]) { +query Requests($instanceId: String!) { + requests(exclude: [DONE, CRITICAL], instanceId: $instanceId) { ...ListAssignation } } diff --git a/graphql/rekuest/queries/node.graphql b/graphql/rekuest/queries/node.graphql index 40a625a..7db1a26 100644 --- a/graphql/rekuest/queries/node.graphql +++ b/graphql/rekuest/queries/node.graphql @@ -1,5 +1,17 @@ -query DetailNode($id: ID, $hash: String) { - node(id: $id, hash: $hash) { +query DetailNode( + $id: ID + $hash: String + $reservation: ID + $template: ID + $assignation: ID +) { + node( + id: $id + hash: $hash + reservation: $reservation + template: $template + assignation: $assignation + ) { ...DetailNode } } @@ -25,6 +37,7 @@ query Nodes( templated: $templated collections: $collections scopes: $scopes + limit: 20 ) { ...NodeListItem } diff --git a/graphql/rekuest/queries/reservation.graphql b/graphql/rekuest/queries/reservation.graphql index 7000fbc..44063a8 100644 --- a/graphql/rekuest/queries/reservation.graphql +++ b/graphql/rekuest/queries/reservation.graphql @@ -34,14 +34,14 @@ query MyReservations { } } -query Reservations { - reservations(exclude: [ENDED, CRITICAL, CANCELLED]) { +query Reservations($instanceId: String!) { + reservations(exclude: [ENDED, CRITICAL, CANCELLED], instanceId: $instanceId) { ...ListReservation } } -query DeployReservations { - reservations(nodeInterfaces: ["fluss:deploy"]) { +query DeployReservations($instanceId: String!) { + reservations(nodeInterfaces: ["fluss:deploy"], instanceId: $instanceId) { id waiter { clientId @@ -61,6 +61,26 @@ query DeployReservations { } } +query ThisFilteredReservations( + $exclude: [ReservationStatusInput] + $filter: [ReservationStatusInput] + $nodeInterfaces: [String] + $templateParams: [TemplateParamInput] + $inputPortDemands: [PortDemandInput] + $instanceId: String! +) { + reservations( + inputPortDemands: $inputPortDemands + nodeInterfaces: $nodeInterfaces + templateParams: $templateParams + exclude: $exclude + filter: $filter + instanceId: $instanceId + ) { + ...ListReservation + } +} + query FilteredReservations( $exclude: [ReservationStatusInput] $filter: [ReservationStatusInput] diff --git a/graphql/rekuest/queries/template.graphql b/graphql/rekuest/queries/template.graphql index 997b52a..6347c9d 100644 --- a/graphql/rekuest/queries/template.graphql +++ b/graphql/rekuest/queries/template.graphql @@ -42,8 +42,18 @@ query AssignableTemplates($node: ID) { } } -query ReservableTemplates($node: ID!) { - reservableTemplates(node: $node) { +query ReservableTemplates( + $node: ID + $templateParams: [TemplateParamInput] + $hash: String + $template: ID +) { + reservableTemplates( + node: $node + template: $template + hash: $hash + templateParams: $templateParams + ) { ...ReservableTemplate } } diff --git a/graphql/rekuest/subscriptions/assignation.graphql b/graphql/rekuest/subscriptions/assignation.graphql index ec57794..28b05b5 100644 --- a/graphql/rekuest/subscriptions/assignation.graphql +++ b/graphql/rekuest/subscriptions/assignation.graphql @@ -10,23 +10,23 @@ subscription WatchAssignation($id: ID!) { subscription WatchMyRequests { myrequests { create { - ...ListAssignation + ...PostmanAssignation } delete update { - ...ListAssignation + ...PostmanAssignation } } } -subscription WatchRequests($identifier: String!) { - requests(identifier: $identifier) { +subscription WatchRequests($instanceId: String!) { + requests(instanceId: $instanceId) { create { - ...ListAssignation + ...PostmanAssignation } delete update { - ...ListAssignation + ...PostmanAssignation } } } @@ -43,8 +43,8 @@ subscription WatchMyTodos { } } -subscription WatchTodos($identifier: String!) { - todos(identifier: $identifier) { +subscription WatchTodos($instanceId: String!) { + todos(instanceId: $instanceId) { create { ...ListAssignation } diff --git a/graphql/rekuest/subscriptions/reservation.graphql b/graphql/rekuest/subscriptions/reservation.graphql index a1af29e..a5b6683 100644 --- a/graphql/rekuest/subscriptions/reservation.graphql +++ b/graphql/rekuest/subscriptions/reservation.graphql @@ -7,14 +7,14 @@ subscription WatchReservation($id: ID!) { } } -subscription WatchReservations($identifier: String!) { - reservations(identifier: $identifier) { +subscription WatchReservations($instanceId: String!) { + reservations(instanceId: $instanceId) { create { - ...ListReservation + ...PostmanReservation } delete update { - ...ListReservation + ...PostmanReservation } } } @@ -32,10 +32,10 @@ subscription WatchMyReservations { } subscription WatchReservationsOnProvision( - $identifier: String! + $instanceId: String! $provision: String! ) { - reservations(identifier: $identifier, provision: $provision) { + reservations(instanceId: $instanceId, provision: $provision) { create { ...ListReservation } diff --git a/knip.ts b/knip.ts new file mode 100644 index 0000000..fea5f79 --- /dev/null +++ b/knip.ts @@ -0,0 +1,8 @@ +import type { KnipConfig } from 'knip'; + +const config: KnipConfig = { + entry: ['src/index.ts'], + project: ['src/**/*.ts'], +}; + +export default config; \ No newline at end of file diff --git a/mikro_next.yml b/mikro_next.yml new file mode 100644 index 0000000..c16b9e3 --- /dev/null +++ b/mikro_next.yml @@ -0,0 +1,20 @@ +overwrite: true +schema: "http://localhost:8030/graphql" +documents: "graphql/mikro_next/**/*.graphql" +generates: + src/mikro_next/api/fragments.ts: + plugins: + - "fragment-matcher" + src/mikro_next/api/graphql.ts: + plugins: + - "typescript" + - "typescript-operations" + - "typescript-react-apollo" + config: + withHooks: true + reactApolloVersion: 3 + arrayInputCoercion: false + + src/mikro_next/graphql.schema.json: + plugins: + - "introspection" diff --git a/package.json b/package.json index 3deacff..03cfa56 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "port": "graphql-codegen --config port.yml", "rekuest": "graphql-codegen --config rekuest.yml", "mikro": "graphql-codegen --config mikro.yml", + "mikro_next": "graphql-codegen --config mikro_next.yml", "herre": "graphql-codegen --config herre.yml", "lok": "graphql-codegen --config lok.yml", "dockbuild": "vite build && docker build -t jhnnsrs/orkestrator:prod .", @@ -22,31 +23,27 @@ "dependencies": { "@air/react-drag-to-select": "^5.0.2", "@apollo/client": "^3.5.10", - "@ebay/nice-modal-react": "^1.2.8", "@formkit/auto-animate": "^1.0.0-beta.1", "@headlessui/react": "^1.5.0", "@heroicons/react": "^1.0.6", "@jhnnsrs/datalayer": "0.0.7", "@jhnnsrs/fakts": "0.1.10", - "@jhnnsrs/herre": "0.0.4", + "@jhnnsrs/herre": "0.0.11", "@popperjs/core": "^2.11.5", + "@radix-ui/react-dialog": "^1.0.4", "@react-spring/web": "^9.5.2", "@reactflow/node-resizer": "^2.0.1", "@tailwindcss/container-queries": "^0.1.0", "@tanstack/react-table": "^8.1.3", "@tauri-apps/api": "^1.3.0", - "@tisoap/react-flow-smart-edge": "^2.0.0", "@types/colormap": "^2.3.1", "@types/dagre": "^0.7.47", - "@types/pathfinding": "^0.0.5", "@types/react-csv": "^1.1.3", "@types/react-dnd-multi-backend": "^6.0.2", "@visx/curve": "^2.1.0", "@visx/glyph": "^2.10.0", "@visx/gradient": "^2.10.0", - "@visx/mock-data": "^2.1.2", "@visx/pattern": "^2.10.0", - "@visx/react-spring": "^2.12.2", "@visx/responsive": "^2.10.0", "@visx/stats": "^2.10.0", "@visx/xychart": "^2.12.2", @@ -56,6 +53,8 @@ "aws4fetch": "^1.0.17", "blurhash": "^2.0.4", "cancelable-promise": "^4.3.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.0.0", "colormap": "^2.3.2", "container-query-polyfill": "^1.0.2", "dagre": "^0.8.5", @@ -63,11 +62,11 @@ "formik": "^2.2.9", "fuse.js": "^6.6.2", "graphiql": "^2.0.4", - "headless-stepper": "^1.6.0", - "idb": "^7.1.1", + "graphql-ws": "^5.14.0", + "handlebars": "^4.7.8", "js-colormaps": "^1.0.0", - "jwt-decode": "^3.1.2", "konva": "^8.3.14", + "lucide-react": "^0.268.0", "pathfinding": "^0.4.18", "pkce-challenge": "^3.0.0", "range-interpolator": "^1.0.2", @@ -82,7 +81,6 @@ "react-dnd-multi-backend": "^7.0.0-alpha.1", "react-dnd-touch-backend": "^16.0.1", "react-dom": "^18.2.0", - "react-flow-renderer": "^10.3.10", "react-graphql-syntax-highlighter": "^0.0.4", "react-icons": "^4.4.0", "react-konva": "^18.2.3", @@ -106,12 +104,12 @@ "react-use-websocket": "^4.2.0", "reactflow": "^11.5.6", "remark-gfm": "^3.0.1", - "rxjs": "^7.5.6", "simple-statistics": "^7.7.6", "slate": "^0.81.1", "slate-react": "^0.81.0", "subscriptions-transport-ws": "^0.11.0", - "threads": "^1.7.0", + "tailwind-merge": "^1.14.0", + "tailwindcss-animate": "^1.0.6", "use-debounce": "^9.0.4", "use-file-picker": "^1.4.2", "use-long-press": "^1.2.0", @@ -132,7 +130,7 @@ "@graphql-codegen/typescript-react-apollo": "^3.3.1", "@tauri-apps/cli": "^1.3.0", "@types/apollo-upload-client": "^17.0.1", - "@types/node": "^18.7.10", + "@types/node": "^20.5.2", "@types/react": "^18.0.15", "@types/react-datepicker": "^4.3.4", "@types/react-dom": "^18.0.6", @@ -141,10 +139,12 @@ "@types/react-slider": "^1.3.1", "@vitejs/plugin-react": "^2.0.0", "autoprefixer": "^10.4.7", + "knip": "^2.19.9", "postcss": "^8.4.14", "sass": "^1.54.9", "serve": "^14.2.0", "tailwindcss": "^3.1.6", + "ts-prune": "^0.10.3", "ts-unused-exports": "^8.0.0", "typescript": "^4.6.4", "vite": "^3.0.2" diff --git a/src/App.tsx b/src/App.tsx index 35c0796..592090a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,655 +1,33 @@ -import { FaktsGuard, FaktsProvider } from "@jhnnsrs/fakts"; -import React, { CSSProperties } from "react"; -import { HTML5Backend } from "react-dnd-html5-backend"; import { Route, BrowserRouter as Router, Routes } from "react-router-dom"; import "react-toastify/dist/ReactToastify.css"; -import { QueryParamProvider } from "use-query-params"; -import { ReactRouter6Adapter } from "use-query-params/adapters/react-router-6"; -import { HealthzGuard } from "./healthz/guard"; +import "./index.css"; import "allotment/dist/style.css"; -import { MouseTransition, Preview } from "react-dnd-multi-backend"; -import "./index.css"; -import { Callback } from "./pages/Callback"; -import { Home } from "./pages/Home"; -import { Port } from "./pages/Port"; -import { Search } from "./pages/Search"; -import { Team } from "./pages/Team"; -import DashBoardHome from "./pages/dashboard/DashboardHome"; -import { DashboardAssignation } from "./pages/dashboard/assignations/DashboardAssignation"; -import { DashboardAssignations } from "./pages/dashboard/assignations/DashboardAssignations"; -import { DashboardNode } from "./pages/dashboard/nodes/DashboardNode"; -import { DashboardNodes } from "./pages/dashboard/nodes/DashboardNodes"; -import { DashboardProvision } from "./pages/dashboard/provisions/DashboardProvision"; -import { DashboardProvisions } from "./pages/dashboard/provisions/DashboardProvisions"; -import { DashboardReservation } from "./pages/dashboard/reservations/DashboardReservation"; -import { DashboardReservations } from "./pages/dashboard/reservations/DashboardReservations"; -import { DashboardTemplate } from "./pages/dashboard/templates/DashboardTemplate"; -import { DashboardTemplates } from "./pages/dashboard/templates/DashboardTemplates"; -import { DataChannel } from "./pages/data/channels/DataChannel"; -import { DataDataset } from "./pages/data/datasets/DataDataset"; -import { DataDatasets } from "./pages/data/datasets/DataDatasets"; -import { DataFile } from "./pages/data/files/DataFile"; -import { DataFiles } from "./pages/data/files/DataFiles"; -import { DataProvenance } from "./pages/data/provenance/DataProvenance"; -import { DataRepresentation } from "./pages/data/representations/DataRepresentation"; -import { DataRepresentations } from "./pages/data/representations/DataRepresentations"; -import { DataSample } from "./pages/data/samples/DataSample"; -import { DataSamples } from "./pages/data/samples/DataSamples"; -import { DataTable } from "./pages/data/tables/DataTable"; -import { DataTables } from "./pages/data/tables/DataTables"; -import { RunScreen } from "./pages/detail/RunScreen"; -import { SnapshotScreen } from "./pages/detail/SnapshotScreen"; -import { TableScreen } from "./pages/detail/TableScreen"; -import { NoRoute } from "./pages/fallbacks/NoRoute"; -import FlowHome from "./pages/flows/FlowHome"; -import TeamHome from "./pages/lok/TeamHome"; -import { PortHome } from "./pages/port/PortHome"; -import { SearchHome } from "./pages/search/SearchHome"; import "./popping.css"; -import { ExperimentalProvider } from "./providers/experimental/provider"; - -import { ProtectedApp } from "./ProtectedApp"; -import { PublicApp } from "./PublicApp"; -import { AdaptiveHerreProvider } from "./bridges/AdaptiveHerreProvider"; -import { TauriFaktsFallback } from "./bridges/TauriFaktsFallback"; -import { TauriHerreCallback } from "./bridges/TauriHerreCallback"; -import { AlerterProvider } from "./components/alerter/alerter-provider"; -import { ConfirmerProvider } from "./components/confirmer/confirmer-provider"; -import { Live } from "./dashboard/Dashboard"; -import { HealthzProvider } from "./healthz/provider"; -import { Fluss } from "./pages/Fluss"; -import { Local } from "./pages/Local"; -import { Settings } from "./pages/Settings"; -import { DashboardAgent } from "./pages/dashboard/agents/DashboardAgent"; -import { DashboardAgents } from "./pages/dashboard/agents/DashboardAgents"; -import { DashboardCollection } from "./pages/dashboard/collections/DashboardCollection"; -import { DashboardCollections } from "./pages/dashboard/collections/DashboardCollections"; -import { DashboardHistory } from "./pages/dashboard/history/DashboardHistory"; -import { DashboardRepositories } from "./pages/dashboard/repositories/DashboardRepositories"; -import { DashboardRepository } from "./pages/dashboard/repositories/DashboardRepository"; -import { DataEra } from "./pages/data/eras/DataEra"; -import { DataEras } from "./pages/data/eras/DataEras"; -import DataGraph from "./pages/data/graphs/DataGraph"; -import DataGraphs from "./pages/data/graphs/DataGraphs"; -import { DataInstrument } from "./pages/data/instruments/DataInstrument"; -import { DataInstruments } from "./pages/data/instruments/DataInstruments"; -import { DataLabel } from "./pages/data/labels/DataLabel"; -import { DataLabels } from "./pages/data/labels/DataLabels"; -import { DataLive } from "./pages/data/live/DataLive"; -import { DataLives } from "./pages/data/live/DataLives"; -import { DataMeta } from "./pages/data/metas/DataMeta"; -import { DataMetas } from "./pages/data/metas/DataMetas"; -import { DataMetric } from "./pages/data/metrics/DataMetric"; -import { DataMetrics } from "./pages/data/metrics/DataMetrics"; -import { DataObjective } from "./pages/data/objectives/DataObjective"; -import { DataObjectives } from "./pages/data/objectives/DataObjectives"; -import { DataPlot } from "./pages/data/plots/DataPlot"; -import { DataPlots } from "./pages/data/plots/DataPlots"; -import { DataPosition } from "./pages/data/positions/DataPosition"; -import { DataPositions } from "./pages/data/positions/DataPositions"; -import { DataRoi } from "./pages/data/rois/DataRoi"; -import { DataStage } from "./pages/data/stages/DataStage"; -import { DataStages } from "./pages/data/stages/DataStages"; -import DataThumbnail from "./pages/data/thumbnails/DataThumbnail"; -import DataThumbnails from "./pages/data/thumbnails/DataThumbnails"; -import { DataTimepoint } from "./pages/data/timepoints/DataTimepoint"; -import { DataTimepoints } from "./pages/data/timepoints/DataTimepoints"; -import DataVideo from "./pages/data/videos/DataVideo"; -import DataVideos from "./pages/data/videos/DataVideos"; -import { FlowTimeline } from "./pages/flows/timelines/FlowTimeline"; -import { FlowDiagram } from "./pages/flows/workspace/FlowDiagram"; -import { FlowDiagramFlow } from "./pages/flows/workspace/FlowDiagramFlow"; -import { FlowDiagramHome } from "./pages/flows/workspace/FlowDiagramHome"; -import { Test } from "./pages/local/Test"; -import { LokApp } from "./pages/lok/apps/LokApp"; -import { LokApps } from "./pages/lok/apps/LokApps"; -import { LokClient } from "./pages/lok/clients/LokClient"; -import { LokClients } from "./pages/lok/clients/LokClients"; -import { LokRelease } from "./pages/lok/releases/LokRelease"; -import { LokReleases } from "./pages/lok/releases/LokReleases"; -import { ManTeam } from "./pages/lok/teams/ManTeam"; -import { ManTeams } from "./pages/lok/teams/ManTeams"; -import { ManUser } from "./pages/lok/users/ManUser"; -import { ManUsers } from "./pages/lok/users/ManUsers"; -import { PortContainer } from "./pages/port/containers/PortContainer"; -import { PortContainers } from "./pages/port/containers/PortContainers"; -import { PortGithubRepo } from "./pages/port/githubrepos/PortGithubRepo"; -import { PortGithubRepos } from "./pages/port/githubrepos/PortGithubRepos"; -import { PortRepoScan } from "./pages/port/reposcans/PortRepoScan"; -import { PortRepoScans } from "./pages/port/reposcans/PortRepoScans"; -import { PortWhale } from "./pages/port/whales/PortWhale"; -import { PortWhales } from "./pages/port/whales/PortWhales"; -import { PublicFakts } from "./pages/public/PublicFakts"; -import { PublicHealthz } from "./pages/public/PublicHealthz"; -import { PublicLogin } from "./pages/public/PublicLogin"; -import { SettingsHome } from "./pages/settings/SettingsHome"; -import { TauriProvider } from "./tauri/provider"; -export const Dashboard = React.lazy(() => import("./pages/Dashboard")); -export const Data = React.lazy(() => import("./pages/Data")); -export const DataHome = React.lazy(() => import("./pages/data/Home")); -export const DataExperiments = React.lazy( - () => import("./pages/data/experiments/DataExperiments") -); -export const DataExperiment = React.lazy( - () => import("./pages/data/experiments/DataExperiment") -); -export const DataModels = React.lazy( - () => import("./pages/data/models/DataModels") -); -export const DataModel = React.lazy( - () => import("./pages/data/models/DataModel") -); -export const DataContexts = React.lazy( - () => import("./pages/data/contexts/DataContexts") -); -export const DataContext = React.lazy( - () => import("./pages/data/contexts/DataContext") -); - -export const DataLink = React.lazy(() => import("./pages/data/links/DataLink")); -export const DataLinks = React.lazy( - () => import("./pages/data/links/DataLinks") -); - -export const HTML5toTouch = { - backends: [ - { - id: "html5", - backend: HTML5Backend, - preview: true, - transition: MouseTransition, - }, - ], -}; -interface Props {} -const Block = ({ - row, - item, - style, -}: { - row: number; - item: any; - style: CSSProperties; -}): JSX.Element => { - return ( -
{JSON.stringify(item)}
- ); -}; - -const ComponentPreview = ({ text }: { text: string }): JSX.Element => { - return ( - { - return ( -
- ); - }} - /> - ); -}; +import { AppProvider } from "./app/AppProvider"; +import { AutoConfiguration } from "./app/AutoConfiguration"; +import { OrkestratorProvider } from "./app/OrkestratorProvider"; +import ProtectedRouter from "./protected/ProtectedRouter"; +import PublicRouter from "./public/PublicRouter"; -export const MainApp: React.FC = (props) => { +function App() { return ( - - - - - - - - ) : ( - - ) - } - > - - }> - - {window.__TAURI__ && } - Loading}> - - {/* Public */} - }> - } /> - } /> - - {/* Private */} - - }> - } /> - - {/* Mikro */} - }> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - - } - /> - } - /> - - } - /> - } - /> - - } - /> - } - /> - - } - /> - } - /> - - } - /> - } - /> - - } - /> - } /> - - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } /> - } - /> - } /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } /> - } - /> - } /> - } - /> - - } /> - - - {/* lok */} - }> - } /> - } - /> - } /> - } - /> - } /> - } /> - } /> - } - /> - } - /> - } - /> - } - /> - - - {/* Fluss */} - - }> - } /> - } - > - } - /> - - } - /> - } - /> - } - /> - } - /> - - - {/* Rekuest */} - }> - } /> - } - /> - - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - - - {/* port */} - }> - } /> - } - /> - } - /> - } - /> - - } - /> - } - /> - } - /> - - } - /> - } - /> - - - } - /> - - } - /> - }> - } /> - - - {/* Settings */} - }> - } /> - - - {/* Tauri */} - }> - } /> - - - } /> - - - - - - - - - - - - - + + + + + {/* Public */} + } /> + {/* Private */} + + }> + + + ); -}; - -function App() { - return ; } export default App; diff --git a/src/ProtectedApp.tsx b/src/ProtectedApp.tsx deleted file mode 100644 index 071a816..0000000 --- a/src/ProtectedApp.tsx +++ /dev/null @@ -1,208 +0,0 @@ -import { HerreGuard } from "@jhnnsrs/herre"; -import React, { CSSProperties } from "react"; -import { HTML5Backend } from "react-dnd-html5-backend"; -import { Outlet } from "react-router-dom"; -import { ToastContainer } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import { GeneralMenu } from "./components/command/GeneralMenu"; -import { GeneralMenuProvider } from "./components/command/GeneralMenuProvider"; -import { NavigationActions } from "./components/command/NavigationActions"; -import { NodesExtension } from "./components/command/NodesExtension"; -import { SearchActions } from "./components/command/SearchActions"; -import { SelectionActions } from "./components/command/SelectionActions"; -import { NavigationBar } from "./components/navigation/NavigationBar"; -import { FlussProvider } from "./fluss/fluss-provider"; -import { FlussWard } from "./fluss/ward"; -import "./index.css"; -import { ManGuard } from "./lok/guard"; -import { ManProvider } from "./lok/provider"; -import { MikroGuard } from "./mikro/MikroGuard"; -import { MikroProvider } from "./mikro/MikroProvider"; -import { MentionListener } from "./mikro/listeners/MentionListener"; -import "./popping.css"; -import { RekuestProvider } from "./rekuest/RekuestProvider"; -import { AgentProvider } from "./rekuest/agent/AgentProvider"; -import { PostmanProvider } from "./rekuest/postman/graphql/postman-provider"; -import { SelectionProvider } from "./rekuest/selection/provider"; -import { WidgetRegistryProvider } from "./rekuest/widgets/widget-provider"; - -import { DndProvider, MouseTransition, Preview } from "react-dnd-multi-backend"; -import { ReserverProvider } from "./rekuest/postman/reserver/reserver-provider"; -import { SettingsProvider } from "./settings/settings-provider"; - -import { DatalayerProvider } from "@jhnnsrs/datalayer"; -import { Actors } from "./actors/Actors"; -import { DatalayerAutoConfigure } from "./bridges/DatalayerAutoConfigure"; -import { FlussAutoConfigure } from "./bridges/FlussAutoConfigure"; -import { LokAutoConfigure } from "./bridges/LokAutoConfigure"; -import { MikroAutoConfigure } from "./bridges/MikroAutoConfigure"; -import { MikroWard } from "./bridges/MikroWard"; -import { PortAutoConfigure } from "./bridges/PortAutoConfigure"; -import { RekuestAutoConfigure } from "./bridges/RekuestAutoConfigure"; -import { RekuestWard } from "./bridges/RekuestWard"; -import { XArrayProvider } from "./experimental/provider/provider"; -import { DialogProvider } from "./layout/dialog/DialogProvider"; -import { PublicLogin } from "./pages/public/PublicLogin"; -import { PortProvider } from "./port/PortProvider"; -import { ExperimentalFeature } from "./providers/experimental/Experimental"; -import { RekuestGuard } from "./rekuest/RekuestGuard"; -import { MaterProvider } from "./rekuest/postman/mater/mater-provider"; -import { RequesterProvider } from "./rekuest/postman/requester/requester-provider"; - -/* try { - import("virtual:pwa-register") - .then((y) => { - const updateSW = y.registerSW({ - onNeedRefresh() { - updateSW(); - }, - onOfflineReady() { - console.log("offline ready"); - }, - }); - }) - .catch((e) => { - console.log(e); - }) - .finally(() => { - console.log("finally"); - }); -} catch (e) { - console.log("no service worker"); -} */ - -export const HTML5toTouch = { - backends: [ - { - id: "html5", - backend: HTML5Backend, - preview: true, - transition: MouseTransition, - }, - ], -}; -interface Props {} - -const Block = ({ - row, - item, - style, -}: { - row: number; - item: any; - style: CSSProperties; -}): JSX.Element => { - return ( -
{JSON.stringify(item)}
- ); -}; - -const ComponentPreview = ({ text }: { text: string }): JSX.Element => { - return ( - { - return ( -
- ); - }} - /> - ); -}; - -export const ProtectedApp: React.FC = () => { - return ( - }> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {" "} - - - - - - - - - - - - - - -
-
- Loading} - > - - {" "} -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ); -}; diff --git a/src/actions/NodeActions.tsx b/src/actions/NodeActions.tsx index f81a413..4f65b45 100644 --- a/src/actions/NodeActions.tsx +++ b/src/actions/NodeActions.tsx @@ -4,7 +4,7 @@ import { ActionButton } from "../layout/ActionButton"; import { Reservation } from "../linker"; import { withRekuest } from "../rekuest"; import { useDeleteNodeMutation } from "../rekuest/api/graphql"; -import { useReserver } from "../rekuest/postman/reserver/reserver-context"; +import { useReserver } from "../rekuest/providers/reserver/reserver-context"; export interface NodeActionsProps { node?: { id?: string } | null; diff --git a/src/app/AppProvider.tsx b/src/app/AppProvider.tsx new file mode 100644 index 0000000..0d28e84 --- /dev/null +++ b/src/app/AppProvider.tsx @@ -0,0 +1,75 @@ +import { DatalayerProvider } from "@jhnnsrs/datalayer"; +import { FaktsProvider } from "@jhnnsrs/fakts"; +import { HerreProvider, windowRedirect } from "@jhnnsrs/herre"; +import { listen } from "@tauri-apps/api/event"; +import { open } from "@tauri-apps/api/shell"; +import React from "react"; +import { FlussProvider } from "../fluss/fluss-provider"; +import { LokProvider } from "../lok/LokProvider"; +import { MikroProvider } from "../mikro/MikroProvider"; +import { MikroNextProvider } from "../mikro_next/MikroNextProvider"; +import { PortProvider } from "../port/PortProvider"; +import { RekuestProvider } from "../rekuest"; +import { AgentProvider } from "../rekuest/agent/AgentProvider"; +import { PostmanProvider } from "../rekuest/providers/postman/postman-provider"; +import { RequesterProvider } from "../rekuest/providers/requester/requester-provider"; +import { ReserverProvider } from "../rekuest/providers/reserver/reserver-provider"; +import { WidgetRegistryProvider } from "../rekuest/widgets/widget-provider"; + +const doRedirect = async (url: string, abortController: AbortController) => { + console.log("Redirecting to", url); + if (window.__TAURI__) { + console.log("Tauri detected"); + open(url); + + return new Promise((resolve, reject) => { + console.log("Listening for code"); + const unlisten = listen("oauth://url", async (event) => { + let url = event.payload as string; + let code = url.split("code=")[1]; + console.log("Got code", code); + resolve(code); + }); + + const unlistend = listen("oauth://invalid-url", async (event) => { + console.log("Got invalid-rl", event); + reject(event); + }); + }); + } else { + return await windowRedirect(url, abortController); + } +}; + +//TODO: Mater provider needs to be seperate +export const AppProvider = ({ children }: { children: React.ReactNode }) => { + return ( + + + + + + + + + + + + + + {children} + + + + + + + + + + + + + + ); +}; diff --git a/src/app/AutoConfiguration.tsx b/src/app/AutoConfiguration.tsx new file mode 100644 index 0000000..f48aa19 --- /dev/null +++ b/src/app/AutoConfiguration.tsx @@ -0,0 +1,145 @@ +import { ToastContainer, ToastContentProps, toast } from "react-toastify"; +import { DatalayerAutoConfigure } from "../bridges/DatalayerAutoConfigure"; +import { FlussAutoConfigure } from "../bridges/FlussAutoConfigure"; +import { LokAutoConfigure } from "../bridges/LokAutoConfigure"; +import { MikroAutoConfigure } from "../bridges/MikroAutoConfigure"; +import { MikroNextAutoConfigure } from "../bridges/MikroNextAutoConfigure"; +import { MikroNextWard } from "../bridges/MikroNextWard"; +import { MikroWard } from "../bridges/MikroWard"; +import { PortAutoConfigure } from "../bridges/PortAutoConfigure"; +import { RekuestAutoConfigure } from "../bridges/RekuestAutoConfigure"; +import { RekuestWard } from "../bridges/RekuestWard"; +import { TauriHerreCallback } from "../bridges/TauriHerreCallback"; +import { GeneralMenu } from "../components/command/GeneralMenu"; +import { NavigationActions } from "../components/command/NavigationActions"; +import { NodesExtension } from "../components/command/NodesExtension"; +import { SearchActions } from "../components/command/SearchActions"; +import { SelectionActions } from "../components/command/SelectionActions"; +import { notEmpty } from "../floating/utils"; +import { FlussWard } from "../fluss/ward"; +import { DialogDisplay } from "../layout/dialog/Dialog"; +import { MikroGuard } from "../mikro/MikroGuard"; +import { MentionListener } from "../mikro/listeners/MentionListener"; +import { withRekuest } from "../rekuest"; +import { RekuestGuard } from "../rekuest/RekuestGuard"; +import { + AssignationStatus, + PostmanAssignationFragment, + useDetailNodeQuery, +} from "../rekuest/api/graphql"; +import { GraphQLPostman } from "../rekuest/providers/postman/GraphQLPostman"; +import { RequestResolver } from "../rekuest/providers/requester/RequestResolver"; +import { ReserveResolver } from "../rekuest/providers/reserver/ReserveResolver"; +import { WidgetsContainer } from "../rekuest/widgets/containers/ReturnWidgetsContainer"; +import { TauriGuard } from "../tauri/guard"; +import { DndPreview } from "../universal/components/DndPreview"; + +const Internal = (props: { assignation: PostmanAssignationFragment }) => { + const { data } = withRekuest(useDetailNodeQuery)({ + variables: { assignation: props.assignation.id }, + }); + + return data?.node?.returns && + props.assignation?.returns && + props.assignation.returns.length >= 0 ? ( + + ) : ( + <>{props.assignation.statusmessage} JSON. + ); +}; + +const Msg = + (ass: PostmanAssignationFragment) => + ({}: ToastContentProps) => { + return ( +
+ +
+ ); + }; + +const CriticalMessageContainer = + (ass: PostmanAssignationFragment) => + ({}: ToastContentProps) => { + return ( +
+ {ass.status} : {ass.statusmessage} +
+ ); + }; + +const DoneMessageContainer = + (ass: PostmanAssignationFragment) => + ({}: ToastContentProps) => { + return
{"Done :)"}
; + }; + +const onAssignUpdate = (ass: PostmanAssignationFragment) => { + console.log(ass); + switch (ass.status) { + case AssignationStatus.Acknowledged: + case AssignationStatus.Bound: + case AssignationStatus.Assigned: { + console.log(ass); + break; + } + case AssignationStatus.Critical: { + toast(CriticalMessageContainer(ass)); + break; + } + case AssignationStatus.Yield: + case AssignationStatus.Returned: { + toast(Msg(ass)); + break; + } + case AssignationStatus.Done: { + toast(DoneMessageContainer(ass)); + break; + } + } +}; + +export const AutoConfiguration = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/app/OrkestratorProvider.tsx b/src/app/OrkestratorProvider.tsx new file mode 100644 index 0000000..d74f071 --- /dev/null +++ b/src/app/OrkestratorProvider.tsx @@ -0,0 +1,62 @@ +import React from "react"; +import { HTML5Backend } from "react-dnd-html5-backend"; + +import { DndProvider, MouseTransition } from "react-dnd-multi-backend"; +import { QueryParamProvider } from "use-query-params"; +import { ReactRouter6Adapter } from "use-query-params/adapters/react-router-6"; +import { GeneralMenuProvider } from "../components/command/GeneralMenuProvider"; +import { DialogProvider } from "../layout/dialog/DialogProvider"; +import { SelectionProvider } from "../rekuest/selection/provider"; +import { SettingsProvider } from "../settings/settings-provider"; + +/* try { + import("virtual:pwa-register") + .then((y) => { + const updateSW = y.registerSW({ + onNeedRefresh() { + updateSW(); + }, + onOfflineReady() { + console.log("offline ready"); + }, + }); + }) + .catch((e) => { + console.log(e); + }) + .finally(() => { + console.log("finally"); + }); +} catch (e) { + console.log("no service worker"); +} */ + +export const HTML5toTouch = { + backends: [ + { + id: "html5", + backend: HTML5Backend, + preview: true, + transition: MouseTransition, + }, + ], +}; +export const OrkestratorProvider = ({ + children, +}: { + children: React.ReactNode; +}) => { + return ( + + + + + + {children} + + + + + + ); +}; diff --git a/src/bridges/AdaptiveFallback.tsx b/src/bridges/AdaptiveFallback.tsx index 196b2f6..efb775f 100644 --- a/src/bridges/AdaptiveFallback.tsx +++ b/src/bridges/AdaptiveFallback.tsx @@ -1,6 +1,6 @@ import { PublicFakts } from "../pages/public/PublicFakts"; import { TauriFaktsFallback } from "./TauriFaktsFallback"; -export const AdaptiveFaktsFallback = (props: any) => { +export const AdaptiveFaktsFallback = () => { return window.__TAURI__ ? : ; }; diff --git a/src/bridges/AdaptiveHerreProvider.tsx b/src/bridges/AdaptiveHerreProvider.tsx deleted file mode 100644 index 60388fb..0000000 --- a/src/bridges/AdaptiveHerreProvider.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { invoke } from "@tauri-apps/api/tauri"; -import { open } from "@tauri-apps/api/shell"; -import React from "react"; -import { useFakts } from "@jhnnsrs/fakts"; -import { HerreProvider } from "@jhnnsrs/herre"; -import { AdaptiveFaktsFallback } from "./AdaptiveFallback"; - -export type FaktsHerreProps = { - children?: React.ReactNode; -}; - -export const AdaptiveHerreProvider: React.FC = (props) => { - const doRedirect = (url: string) => { - console.log("Redirecting to", url); - if (window.__TAURI__) { - open(url); - } else { - window.open(url, "_blank", "noreferrer, popup"); - } - }; - - return ( - {props.children} - ); -}; diff --git a/src/bridges/AdaptiveLogin.tsx b/src/bridges/AdaptiveLogin.tsx index a8f5c06..612bbc3 100644 --- a/src/bridges/AdaptiveLogin.tsx +++ b/src/bridges/AdaptiveLogin.tsx @@ -1,5 +1,3 @@ -import { PublicFakts } from "../pages/public/PublicFakts"; -import { TauriFaktsFallback } from "./TauriFaktsFallback"; import { TauriLogin } from "./TauriLogin"; import { WebLogin } from "./WebLogin"; diff --git a/src/bridges/DatalayerAutoConfigure.tsx b/src/bridges/DatalayerAutoConfigure.tsx index 736311a..3d65c65 100644 --- a/src/bridges/DatalayerAutoConfigure.tsx +++ b/src/bridges/DatalayerAutoConfigure.tsx @@ -1,14 +1,13 @@ +import { useDatalayer } from "@jhnnsrs/datalayer"; import { useFakts } from "@jhnnsrs/fakts"; import React, { useEffect } from "react"; -import { useDatalayer } from "@jhnnsrs/datalayer"; -import result from "../mikro/api/fragments"; +import { useMikro } from "../mikro/MikroContext"; import { PresignDocument, PresignMutation, RequestDocument, RequestQuery, } from "../mikro/api/graphql"; -import { useMikro } from "../mikro/MikroContext"; export const DatalayerAutoConfigure: React.FC<{}> = (props) => { const { client } = useMikro(); diff --git a/src/bridges/FlussAutoConfigure.tsx b/src/bridges/FlussAutoConfigure.tsx index 089e002..b35787c 100644 --- a/src/bridges/FlussAutoConfigure.tsx +++ b/src/bridges/FlussAutoConfigure.tsx @@ -1,9 +1,8 @@ -import React, { useEffect } from "react"; import { useFakts } from "@jhnnsrs/fakts"; import { useHerre } from "@jhnnsrs/herre"; -import { usePort } from "../port/PortContext"; -import result from "../port/api/fragments"; +import React, { useEffect } from "react"; import { useFluss } from "../fluss/fluss-context"; +import result from "../port/api/fragments"; export const FlussAutoConfigure: React.FC<{}> = (props) => { const { configure } = useFluss(); diff --git a/src/bridges/LokAutoConfigure.tsx b/src/bridges/LokAutoConfigure.tsx index 98de317..2d4240e 100644 --- a/src/bridges/LokAutoConfigure.tsx +++ b/src/bridges/LokAutoConfigure.tsx @@ -1,11 +1,11 @@ -import React, { useEffect } from "react"; import { useFakts } from "@jhnnsrs/fakts"; import { useHerre } from "@jhnnsrs/herre"; -import { useMan } from "../lok/context"; +import React, { useEffect } from "react"; +import { useLok } from "../lok/LokContext"; import result from "../lok/api/fragments"; export const LokAutoConfigure: React.FC<{}> = (props) => { - const { configure } = useMan(); + const { configure } = useLok(); const { token } = useHerre(); const { fakts } = useFakts(); diff --git a/src/bridges/MikroAutoConfigure.tsx b/src/bridges/MikroAutoConfigure.tsx index 39a2e61..dc74a7d 100644 --- a/src/bridges/MikroAutoConfigure.tsx +++ b/src/bridges/MikroAutoConfigure.tsx @@ -1,6 +1,6 @@ -import React, { useEffect } from "react"; import { useFakts } from "@jhnnsrs/fakts"; import { useHerre } from "@jhnnsrs/herre"; +import React, { useEffect } from "react"; import { useMikro } from "../mikro/MikroContext"; import result from "../mikro/api/fragments"; @@ -18,13 +18,9 @@ export const MikroAutoConfigure: React.FC<{}> = (props) => { endpointUrl: fakts.mikro.endpoint_url, possibleTypes: result.possibleTypes, retrieveToken: () => token, - s3resolve: (path?: string | null) => { - if (path) { - return `${fakts.minio?.endpoint_url}${path}`; - } - return "fallback"; - }, }); + } else { + configure(undefined); } }, [token, fakts]); diff --git a/src/bridges/MikroNextAutoConfigure.tsx b/src/bridges/MikroNextAutoConfigure.tsx new file mode 100644 index 0000000..04879fe --- /dev/null +++ b/src/bridges/MikroNextAutoConfigure.tsx @@ -0,0 +1,29 @@ +import { useFakts } from "@jhnnsrs/fakts"; +import { useHerre } from "@jhnnsrs/herre"; +import React, { useEffect } from "react"; +import { useMikroNext } from "../mikro_next/MikroNextContext"; +import result from "../mikro_next/api/fragments"; + +export const MikroNextAutoConfigure: React.FC<{}> = (props) => { + const { configure } = useMikroNext(); + const { token } = useHerre(); + const { fakts } = useFakts(); + + useEffect(() => { + if (token && fakts.mikro_new) { + configure({ + secure: fakts.mikro_new.secure, + datalayer: fakts.mikro_new.datalayer, + wsEndpointUrl: fakts.mikro_new.ws_endpoint_url, + endpointUrl: fakts.mikro_new.endpoint_url, + possibleTypes: result.possibleTypes, + retrieveToken: () => token, + }); + } + else { + configure(undefined); + } + }, [token, fakts]); + + return <> ; +}; diff --git a/src/bridges/MikroNextWard.tsx b/src/bridges/MikroNextWard.tsx new file mode 100644 index 0000000..887d2d2 --- /dev/null +++ b/src/bridges/MikroNextWard.tsx @@ -0,0 +1,56 @@ +import { gql } from "@apollo/client"; +import React, { useEffect } from "react"; +import { withMikro } from "../mikro/MikroContext"; +import { useDetailMetricQuery } from "../mikro/api/graphql"; +import { useMikroNext } from "../mikro_next/MikroNextContext"; +import { useWidgetRegistry } from "../rekuest/widgets/widget-context"; + +export const MetricWidget = (props: any) => { + const { data } = withMikro(useDetailMetricQuery)({ + variables: { + id: props.value, + }, + }); + + return ( +
+
{data?.metric?.key}
+
{JSON.stringify(data?.metric?.value)}
+
+ ); +}; + +export const MikroNextWard: React.FC<{ + key?: string; + fallback?: React.ReactNode; +}> = ({ key, fallback }) => { + const { client } = useMikroNext(); + const { registry } = useWidgetRegistry(); + + useEffect(() => { + if (client) { + const runFunc = (options: { query: string; variables: any }) => { + let document = gql(options.query); + return client + .query({ + query: document, + variables: options.variables, + }) + .then((result: any) => result.data); + }; + + const resolveHook = (hook: string | undefined | null) => { + if (hook == "metric") { + return (value: any) => ; + } + }; + + registry?.registerWard("mikro_new", { + search: runFunc, + hook: resolveHook, + }); + } + }, [client, registry]); + + return <>; +}; diff --git a/src/bridges/MikroWard.tsx b/src/bridges/MikroWard.tsx index 524834e..3b43c85 100644 --- a/src/bridges/MikroWard.tsx +++ b/src/bridges/MikroWard.tsx @@ -1,8 +1,8 @@ import { gql } from "@apollo/client"; +import { useDatalayer } from "@jhnnsrs/datalayer"; import React, { useEffect } from "react"; -import { useDetailMetricQuery } from "../mikro/api/graphql"; import { useMikro, withMikro } from "../mikro/MikroContext"; -import { useRekuest } from "../rekuest/RekuestContext"; +import { useDetailMetricQuery } from "../mikro/api/graphql"; import { useWidgetRegistry } from "../rekuest/widgets/widget-context"; export const MetricWidget = (props: any) => { @@ -23,10 +23,10 @@ export const MetricWidget = (props: any) => { export const MikroWard: React.FC<{ key?: string; fallback?: React.ReactNode; - children: React.ReactNode; -}> = ({ key, children, fallback }) => { - const { client, s3resolve } = useMikro(); +}> = ({ key, fallback }) => { + const { client } = useMikro(); const { registry } = useWidgetRegistry(); + const { s3resolve } = useDatalayer(); useEffect(() => { if (client) { @@ -65,5 +65,5 @@ export const MikroWard: React.FC<{ } }, [client, registry]); - return <>{children}; + return <>; }; diff --git a/src/bridges/RekuestAutoConfigure.tsx b/src/bridges/RekuestAutoConfigure.tsx index b4012c2..0d97309 100644 --- a/src/bridges/RekuestAutoConfigure.tsx +++ b/src/bridges/RekuestAutoConfigure.tsx @@ -21,6 +21,8 @@ export const RekuestAutoConfigure: React.FC<{}> = (props) => { possibleTypes: result.possibleTypes, retrieveToken: () => token, }); + } else { + configure(undefined); } }, [token, fakts]); diff --git a/src/bridges/RekuestWard.tsx b/src/bridges/RekuestWard.tsx index a196888..2de89dd 100644 --- a/src/bridges/RekuestWard.tsx +++ b/src/bridges/RekuestWard.tsx @@ -6,8 +6,7 @@ import { useWidgetRegistry } from "../rekuest/widgets/widget-context"; export const RekuestWard: React.FC<{ key?: string; fallback?: React.ReactNode; - children?: React.ReactNode; -}> = ({ key, children, fallback }) => { +}> = ({ key, fallback }) => { const { client } = useRekuest(); const { registry } = useWidgetRegistry(); @@ -38,5 +37,5 @@ export const RekuestWard: React.FC<{ } }, [client, registry]); - return <>{children}; + return <>; }; diff --git a/src/components/DeployedFlows.tsx b/src/components/DeployedFlows.tsx index fdfef80..0a73ffd 100644 --- a/src/components/DeployedFlows.tsx +++ b/src/components/DeployedFlows.tsx @@ -1,11 +1,10 @@ import React from "react"; -import { useNavigate } from "react-router"; import { notEmpty } from "../floating/utils"; import { SectionTitle } from "../layout/SectionTitle"; import { Reservation } from "../linker"; import { useRequesterMate } from "../mates/reservation/useRequesterMate"; import { ReservationStatus } from "../rekuest/api/graphql"; -import { useReserver } from "../rekuest/postman/reserver/reserver-context"; +import { useReserver } from "../rekuest/providers/reserver/reserver-context"; import { colorFromReservationStatus } from "../rekuest/utils"; import { ResponsiveGrid } from "./layout/ResponsiveGrid"; diff --git a/src/components/Generators.tsx b/src/components/Generators.tsx index 8b060df..077f29f 100644 --- a/src/components/Generators.tsx +++ b/src/components/Generators.tsx @@ -2,8 +2,8 @@ import { useAutoAnimate } from "@formkit/auto-animate/react"; import React from "react"; import { ActionButton } from "../layout/ActionButton"; import { NodeKind, ReservationStatus } from "../rekuest/api/graphql"; -import { useRequester } from "../rekuest/postman/requester/requester-context"; -import { useReserver } from "../rekuest/postman/reserver/reserver-context"; +import { useRequester } from "../rekuest/providers/requester/requester-context"; +import { useReserver } from "../rekuest/providers/reserver/reserver-context"; export type IGeneratorsProps = {}; diff --git a/src/components/MyAgents.tsx b/src/components/MyAgents.tsx index a506cb3..6771b47 100644 --- a/src/components/MyAgents.tsx +++ b/src/components/MyAgents.tsx @@ -5,9 +5,9 @@ import { SectionTitle } from "../layout/SectionTitle"; import { useBounceAgentMate } from "../mates/agent/useBounceAgentMate"; import { useDeleteAgentMate } from "../mates/agent/useDeleteAgentMate"; import { useKickAgentMate } from "../mates/agent/useKickAgentMate"; -import { ListAgentFragment } from "../rekuest/api/graphql"; +import { withRekuest } from "../rekuest"; +import { ListAgentFragment, useMyAgentsQuery } from "../rekuest/api/graphql"; import { AgentCard } from "../rekuest/components/cards/AgentCard"; -import { usePostman } from "../rekuest/postman/graphql/postman-context"; import { ResponsiveContainerGrid } from "./layout/ResponsiveContainerGrid"; export type IActiveClientsProps = {}; @@ -15,9 +15,12 @@ export type IActiveClientsProps = {}; export const AgentItem = ({ agent }: { agent: ListAgentFragment }) => {}; const MyAgents: React.FC = ({}) => { - const { agents: data } = usePostman(); const navigate = useNavigate(); + const { data } = withRekuest(useMyAgentsQuery)({ + fetchPolicy: "cache-and-network", + }); + const kickagent = useKickAgentMate(); const bounceagent = useBounceAgentMate(); const deleteagent = useDeleteAgentMate(); diff --git a/src/components/MyAssignations.tsx b/src/components/MyAssignations.tsx index 580a1da..4a956d6 100644 --- a/src/components/MyAssignations.tsx +++ b/src/components/MyAssignations.tsx @@ -1,10 +1,10 @@ import React from "react"; -import { useNavigate } from "react-router"; import { ListRender } from "../layout/SectionTitle"; import { Assignation } from "../linker"; import { useAssignationMate } from "../mates/assignation/useAssignationMates"; -import { AssignationStatus } from "../rekuest/api/graphql"; -import { usePostman } from "../rekuest/postman/graphql/postman-context"; +import { withRekuest } from "../rekuest"; +import { AssignationStatus, useRequestsQuery } from "../rekuest/api/graphql"; +import { useSettings } from "../settings/settings-context"; export type IMyReservationsProps = {}; const colorFromStatus = (status: AssignationStatus | undefined) => { @@ -31,15 +31,19 @@ const colorFromStatus = (status: AssignationStatus | undefined) => { }; const MyAssignations: React.FC = () => { - const { requests, unassign, ack } = usePostman(); + const { settings } = useSettings(); + const { data } = withRekuest(useRequestsQuery)({ + variables: { + instanceId: settings.instanceId, + }, + }); - const navigate = useNavigate(); const assignationMate = useAssignationMate(); return ( <> ![ AssignationStatus.Returned, @@ -88,7 +92,7 @@ const MyAssignations: React.FC = () => { )} + array={data?.requests?.filter((ass) => [ AssignationStatus.Returned, AssignationStatus.Cancelled, diff --git a/src/components/MyBigFiles.tsx b/src/components/MyBigFiles.tsx index 1bf6c84..c25bca0 100644 --- a/src/components/MyBigFiles.tsx +++ b/src/components/MyBigFiles.tsx @@ -3,7 +3,7 @@ import { useDrop } from "react-dnd"; import { NativeTypes } from "react-dnd-html5-backend"; import { Offsetter, SectionTitle } from "../layout/SectionTitle"; import { MikroFile } from "../linker"; -import { useMikro, withMikro } from "../mikro/MikroContext"; +import { withMikro } from "../mikro/MikroContext"; import { MyOmeroFilesDocument, MyOmeroFilesQuery, @@ -49,7 +49,7 @@ const MyBigFiles: React.FC = ({ const [pendingFutures, setPendingFutures] = useState([]); const { upload } = useDatalayer(); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); const deleteFileMate = useDeleteFileMate(); const downloadFileMate = useDownloadFileMate(); diff --git a/src/components/MyFiles.tsx b/src/components/MyFiles.tsx index 1288a14..3f0d448 100644 --- a/src/components/MyFiles.tsx +++ b/src/components/MyFiles.tsx @@ -1,36 +1,21 @@ import React, { useEffect, useState } from "react"; -import { - BsCaretLeft, - BsCaretRight, - BsDownload, - BsPlusCircle, - BsTrash, -} from "react-icons/bs"; -import { ImCancelCircle } from "react-icons/im"; import { useDrop } from "react-dnd"; import { NativeTypes } from "react-dnd-html5-backend"; -import { Mate } from "../rekuest/postman/mater/mater-context"; +import { BsCaretLeft, BsCaretRight } from "react-icons/bs"; +import { notEmpty } from "../floating/utils"; import { SectionTitle } from "../layout/SectionTitle"; import { MikroFile } from "../linker"; +import { useDeleteFileMate } from "../mates/file/useDeleteFileMate"; +import { useDownloadFileMate } from "../mates/file/useDownloadFileMate"; +import { withMikro } from "../mikro/MikroContext"; import { MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, useMyOmeroFilesQuery, useUploadOmeroFileMutation, } from "../mikro/api/graphql"; -import { useMikro, withMikro } from "../mikro/MikroContext"; -import { useConfirm } from "./confirmer/confirmer-context"; -import { ResponsiveGrid } from "./layout/ResponsiveGrid"; -import { preventOverflow } from "@popperjs/core"; -import { Icons } from "react-toastify"; -import { ResponsiveContainerGrid } from "./layout/ResponsiveContainerGrid"; -import { DataHomeFilterParams } from "../pages/data/Home"; -import { notEmpty } from "../floating/utils"; import { FileCard } from "../mikro/components/cards/FileCard"; -import { useDownloadFileMate } from "../mates/file/useDownloadFileMate"; -import { useDeleteFileMate } from "../mates/file/useDeleteFileMate"; +import { DataHomeFilterParams } from "../pages/data/Home"; +import { ResponsiveContainerGrid } from "./layout/ResponsiveContainerGrid"; export type IMyRepresentationsProps = {}; const limit = 20; @@ -57,7 +42,7 @@ const MyFiles: React.FC = ({ const [uploadFutures, setUploadFutures] = useState([]); const [pendingFutures, setPendingFutures] = useState([]); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); const variables = { limit: limit, offset: 0, createdDay: createdDay }; diff --git a/src/components/MyRepresentations.tsx b/src/components/MyRepresentations.tsx index 49e738a..60b33b9 100644 --- a/src/components/MyRepresentations.tsx +++ b/src/components/MyRepresentations.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react"; import { ListRender } from "../layout/SectionTitle"; import { Representation } from "../linker"; import { useMikroLinkMate } from "../mates/generics/useLinkMate"; +import { usePostmanMate } from "../mates/postman/usePostmanMates"; import { withMikro } from "../mikro/MikroContext"; import { MyRepresentationsEventDocument, @@ -22,6 +23,7 @@ const MyRepresentations: React.FC< const [offset, setOffset] = useState(0); const mikroLinkMate = useMikroLinkMate(); + const postmanMate = usePostmanMate(); const { data, loading, subscribeToMore, refetch } = withMikro( useMyRepresentationsQuery @@ -92,13 +94,17 @@ const MyRepresentations: React.FC< loading={loading} title={ - Images + Imagesssss } refetch={refetch} > {(rep, index) => ( - + )} diff --git a/src/components/MyReservations.tsx b/src/components/MyReservations.tsx index f81f5ff..d3b4b6a 100644 --- a/src/components/MyReservations.tsx +++ b/src/components/MyReservations.tsx @@ -1,21 +1,22 @@ import React from "react"; -import { - ListReservationFragment, - ReservationStatus, - useMyReservationsQuery, -} from "../rekuest/api/graphql"; -import { AdditionalMate, Mate } from "../rekuest/postman/mater/mater-context"; -import { useRequester } from "../rekuest/postman/requester/requester-context"; -import { useReserver } from "../rekuest/postman/reserver/reserver-context"; import { notEmpty } from "../floating/utils"; import { Reservation } from "../linker"; -import { ResponsiveGrid } from "./layout/ResponsiveGrid"; -import { withRekuest } from "../rekuest"; import { useRequesterMate } from "../mates/reservation/useRequesterMate"; +import { withRekuest } from "../rekuest"; +import { useReservationsQuery } from "../rekuest/api/graphql"; import { ReservationCard } from "../rekuest/components/cards/ReservationCard"; +import { useSettings } from "../settings/settings-context"; +import { ResponsiveGrid } from "./layout/ResponsiveGrid"; const MyReservations: React.FC<{}> = () => { - const { data } = withRekuest(useMyReservationsQuery)(); + const { settings } = useSettings(); + + const { data } = withRekuest(useReservationsQuery)({ + fetchPolicy: "cache-and-network", + variables: { + instanceId: settings.instanceId, + }, + }); const requesterMate = useRequesterMate(); return ( @@ -26,7 +27,7 @@ const MyReservations: React.FC<{}> = () => { - {data?.myreservations?.filter(notEmpty).map((res, index) => ( + {data?.reservations?.filter(notEmpty).map((res, index) => ( = () => { const [offset, setOffset] = useState(0); - const { data } = withMan(useMyGroupsQuery)({ + const { data } = withLok(useMyGroupsQuery)({ //pollInterval: 1000, }); diff --git a/src/components/PositionCanvas.tsx b/src/components/PositionCanvas.tsx index 82a1c29..3a5289f 100644 --- a/src/components/PositionCanvas.tsx +++ b/src/components/PositionCanvas.tsx @@ -4,7 +4,6 @@ import React, { useState } from "react"; import { Circle, Layer, Line, Rect, Stage } from "react-konva"; import { useNavigate } from "react-router"; import { Position } from "../linker"; -import { useMikro } from "../mikro/MikroContext"; import { ListPositionFragment } from "../mikro/api/graphql"; import { useModelSelector } from "../rekuest/selection/context"; @@ -34,7 +33,7 @@ export const PositionCanvas = ({ setIsMultiSelecting, } = useModelSelector(); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); let calculateXSize = (pos: ListPositionFragment) => { return ( diff --git a/src/components/Producers.tsx b/src/components/Producers.tsx index 0e4a832..239d2f2 100644 --- a/src/components/Producers.tsx +++ b/src/components/Producers.tsx @@ -1,8 +1,8 @@ import React from "react"; import { ActionButton } from "../layout/ActionButton"; import { NodeKind, ReservationStatus } from "../rekuest/api/graphql"; -import { useRequester } from "../rekuest/postman/requester/requester-context"; -import { useReserver } from "../rekuest/postman/reserver/reserver-context"; +import { useRequester } from "../rekuest/providers/requester/requester-context"; +import { useReserver } from "../rekuest/providers/reserver/reserver-context"; export type IProducersProps = {}; diff --git a/src/components/Provisions.tsx b/src/components/Provisions.tsx index ed1723c..8f8b885 100644 --- a/src/components/Provisions.tsx +++ b/src/components/Provisions.tsx @@ -1,21 +1,13 @@ import React from "react"; -import { - BsCaretLeft, - BsCaretRight, - BsCheckCircle, - BsExclamationTriangle, - BsPlusCircle, - BsTrash, -} from "react-icons/bs"; +import { BsCheckCircle, BsExclamationTriangle } from "react-icons/bs"; import { useNavigate } from "react-router"; -import { ProvisionStatus } from "../rekuest/api/graphql"; -import { UnprovideButton } from "../rekuest/components/UnprovideButton"; -import { usePostman } from "../rekuest/postman/graphql/postman-context"; -import { colorFromProvisionStatus } from "../rekuest/ui/utils"; import { notEmpty } from "../floating/utils"; import { Provision } from "../linker"; import { UserEmblem } from "../lok/components/UserEmblem"; -import { ResponsiveGrid } from "./layout/ResponsiveGrid"; +import { ProvisionStatus } from "../rekuest/api/graphql"; +import { UnprovideButton } from "../rekuest/components/UnprovideButton"; +import { usePostman } from "../rekuest/providers/legacy/postman-context"; +import { colorFromProvisionStatus } from "../rekuest/ui/utils"; import { ResponsiveContainerGrid } from "./layout/ResponsiveContainerGrid"; export type IMyProvisionsProps = {}; diff --git a/src/components/Reservations.tsx b/src/components/Reservations.tsx index d3cc0fa..f7376af 100644 --- a/src/components/Reservations.tsx +++ b/src/components/Reservations.tsx @@ -2,14 +2,22 @@ import React from "react"; import { notEmpty } from "../floating/utils"; import { Reservation } from "../linker"; import { useRequesterMate } from "../mates/reservation/useRequesterMate"; +import { withRekuest } from "../rekuest"; +import { useReservationsQuery } from "../rekuest/api/graphql"; import { ReservationCard } from "../rekuest/components/cards/ReservationCard"; -import { useReserver } from "../rekuest/postman/reserver/reserver-context"; +import { useSettings } from "../settings/settings-context"; import { ResponsiveContainerGrid } from "./layout/ResponsiveContainerGrid"; export type IMyReservationsProps = {}; const Reservations: React.FC = () => { - const { reservations } = useReserver(); + const { settings } = useSettings(); + const { data } = withRekuest(useReservationsQuery)({ + fetchPolicy: "cache-and-network", + variables: { + instanceId: settings.instanceId, + }, + }); const requesterMate = useRequesterMate(); return ( @@ -19,7 +27,7 @@ const Reservations: React.FC = () => {
- {reservations?.reservations?.filter(notEmpty).map((res, index) => ( + {data?.reservations?.filter(notEmpty).map((res, index) => ( = () => { const [offset, setOffset] = useState(0); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); const { data: reps, subscribeToMore, diff --git a/src/components/ThumbnailCanvas.tsx b/src/components/ThumbnailCanvas.tsx index 265e7af..c1068ae 100644 --- a/src/components/ThumbnailCanvas.tsx +++ b/src/components/ThumbnailCanvas.tsx @@ -1,17 +1,17 @@ +import { useDatalayer } from "@jhnnsrs/datalayer"; import { decode } from "blurhash"; import React from "react"; import { Layer, Line, Stage, Text } from "react-konva"; import { useNavigate } from "react-router"; import { notEmpty } from "../floating/utils"; import { Roi } from "../linker"; +import { withLok } from "../lok/LokContext"; import { useUserQuery } from "../lok/api/graphql"; -import { withMan } from "../lok/man"; import { DetailRepresentationFragment, RepRoiFragment, RoiType, } from "../mikro/api/graphql"; -import { useMikro } from "../mikro/MikroContext"; interface ThumbnailCanvasProps { rep: DetailRepresentationFragment; @@ -32,7 +32,7 @@ export const RoiLabel = ({ roi: RepRoiFragment; translate: any; }) => { - const { data, error } = withMan(useUserQuery)({ + const { data, error } = withLok(useUserQuery)({ variables: { id: roi.creator?.sub }, }); @@ -64,7 +64,7 @@ export const ThumbnailCanvas = ({ const [highlight, setHighlight] = React.useState( undefined ); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); const translate = ( x: number | null | undefined, diff --git a/src/components/command/GeneralMenu.tsx b/src/components/command/GeneralMenu.tsx index c2e4b20..8841d5d 100644 --- a/src/components/command/GeneralMenu.tsx +++ b/src/components/command/GeneralMenu.tsx @@ -85,7 +85,6 @@ export const GeneralMenu = () => { useEffect(() => { if (query || query.length > 0) { - console.log("nanan", query.length); let x = extensions.map((handler) => handler .filter({ query: query, modifiers: modifiers, open: open }) @@ -93,19 +92,20 @@ export const GeneralMenu = () => { ); Promise.all(x) - .then((results) => - results.reduce((prev, curr) => ({ ...prev, ...curr }), { + .then((results) => { + console.log(results); + return results.reduce((prev, curr) => ({ ...prev, ...curr }), { modify: modifyingActions.filter((a) => a.label.toLowerCase().includes(query.toLowerCase()) ), actions: actions.filter((a) => a.label.toLowerCase().includes(query.toLowerCase()) ), - }) - ) - .then(setOrderedActions); + }); + }) + .then(setOrderedActions) + .catch((e) => console.error(e)); } else { - console.log("Setting actions", actions); setOrderedActions({ actions: actions, }); diff --git a/src/components/command/NodesExtension.tsx b/src/components/command/NodesExtension.tsx index 4368dff..bdf7b7c 100644 --- a/src/components/command/NodesExtension.tsx +++ b/src/components/command/NodesExtension.tsx @@ -1,12 +1,16 @@ -import React from "react"; +import React, { useEffect } from "react"; import { useNavigate } from "react-router"; import { Node } from "../../linker"; -import { withRekuest } from "../../rekuest"; -import { useNodesLazyQuery } from "../../rekuest/api/graphql"; -import { useRequester } from "../../rekuest/postman/requester/requester-context"; -import { useReserver } from "../../rekuest/postman/reserver/reserver-context"; +import { useRekuest } from "../../rekuest"; +import { NodesDocument, NodesQuery } from "../../rekuest/api/graphql"; +import { useRequester } from "../../rekuest/providers/requester/requester-context"; +import { useReserver } from "../../rekuest/providers/reserver/reserver-context"; import { queryfiltered } from "./GeneralMenu"; -import { Extension, ModifyingAction, useExtension } from "./GeneralMenuContext"; +import { + Extension, + ModifyingAction, + useGeneralMenu, +} from "./GeneralMenuContext"; export interface NavigationActionsProps {} @@ -20,89 +24,95 @@ export type ReserveModifierParams = { }; export const NodesExtension: React.FC = ({}) => { - const [searchNodes] = withRekuest(useNodesLazyQuery)({ - fetchPolicy: "network-only", - }); + const { client } = useRekuest(); + const navigate = useNavigate(); const { reserve } = useReserver(); const { assign } = useRequester(); - const navigate = useNavigate(); + const { registerExtension, unregisterExtension } = useGeneralMenu(); - const handler: Extension = { - key: "nodesearch", - label: "Nodes", - filter: async ({ query, modifiers }) => { - if (modifiers.find((x) => x.key == "search")) { - return []; - } + useEffect(() => { + if (client) { + const handler: Extension = { + key: "nodesearch", + label: "Nodes", + filter: async ({ query, modifiers }) => { + if (modifiers.find((x) => x.key == "search")) { + return []; + } - let nodemodifier = modifiers.find( - (x) => x.key == "node" - ) as ModifyingAction; - if (nodemodifier) { - return queryfiltered( - [ - { - custom: async (action) => { - navigate(Node.linkBuilder(nodemodifier?.params?.node)); - }, - key: "node-navigate", - label: "Navigate", - }, - { - custom: async (action) => { - let r = await reserve({ node: nodemodifier?.params?.node }); + let nodemodifier = modifiers.find( + (x) => x.key == "node" + ) as ModifyingAction; + if (nodemodifier) { + return queryfiltered( + [ + { + custom: async (action) => { + navigate(Node.linkBuilder(nodemodifier?.params?.node)); + }, + key: "node-navigate", + label: "Navigate", + }, + { + custom: async (action) => { + let r = await reserve({ node: nodemodifier?.params?.node }); - return { - modifiers: modifiers - .concat({ - key: "reserve", - label: "Reserved", - params: { - reserve: r?.id, - type: "reserve", - }, - }) - .filter((m) => m.key != "node"), - open: true, - }; - }, - key: "node-navigate", - label: "Reserve", - }, - ], - query - ); - } + return { + modifiers: modifiers + .concat({ + key: "reserve", + label: "Reserved", + params: { + reserve: r?.id, + type: "reserve", + }, + }) + .filter((m) => m.key != "node"), + open: true, + }; + }, + key: "node-navigate", + label: "Reserve", + }, + ], + query + ); + } - console.log("FIltering"); + let nodes = await client.query({ + query: NodesDocument, + variables: { search: query }, + }); - let nodes = await searchNodes({ - variables: { search: query }, - }); + console.log("Nodes", nodes?.data?.allnodes); - let nodeActions = nodes?.data?.allnodes?.map((node) => { - return { - extension: "modify", - label: node?.name || "unknown", - key: "node", - params: { - type: "node", - node: node?.id, - }, - description: node?.description, - }; - }); + let nodeActions = nodes?.data?.allnodes?.map((node) => { + return { + extension: "modify", + label: node?.name || "unknown", + key: "node", + params: { + type: "node", + node: node?.id, + }, + description: node?.description, + }; + }); - return queryfiltered(nodeActions, query); - }, - do: async ({ key, params }) => { - console.log("Doing", key, params); - }, - }; + return queryfiltered(nodeActions, query); + }, + do: async ({ key, params }) => { + console.log("Doing", key, params); + }, + }; + console.log("Registering Extensions ", handler); + registerExtension(handler); - useExtension(handler); + return () => unregisterExtension(handler.key); + } + }, [client]); return <>; }; diff --git a/src/components/forms/fields/SearchInput.tsx b/src/components/forms/fields/SearchInput.tsx index 6506e73..668a5aa 100644 --- a/src/components/forms/fields/SearchInput.tsx +++ b/src/components/forms/fields/SearchInput.tsx @@ -5,7 +5,7 @@ import { Fragment, useEffect, useState } from "react"; import { useDrop } from "react-dnd"; import { IoMdCheckmarkCircleOutline } from "react-icons/io"; import { notEmpty } from "../../../floating/utils"; -import { Partner } from "../../../rekuest/postman/mater/mater-context"; +import { Partner } from "../../../rekuest/providers/mater/mater-context"; import { Alert } from "../Alert"; import { wrapped } from "./Wrapper"; import { CommonFieldProps } from "./types"; @@ -13,7 +13,7 @@ import { CommonFieldProps } from "./types"; export type Option = { label: string; value: any; - description?: string; + description?: string | null | undefined; }; export type CommonProps = { name: string; @@ -112,6 +112,7 @@ export const OptionItem = ({ option }: { option: Option }) => ( } > {option.label} + {option.description && ({option.description})} ); @@ -133,6 +134,7 @@ export const MultiItem = ({ option }: { option: Option }) => ( }`} > {option.label} + {option.description && ({option.description})} {selected ? ( = ({ children }) => { + + + ` dark:hover:text-back-400 px-2 py-2 hidden md:block + } ${isActive ? "dark:text-back-400" : "text-back-500"}` + } + > + + + = ({ children }) => { - + = ({ children }) => { > - + @@ -178,7 +191,9 @@ const NavigationBar: React.FC = ({ children }) => { - + + +
); diff --git a/src/components/navigation/UserIcon.tsx b/src/components/navigation/UserIcon.tsx index d94eff7..748993a 100644 --- a/src/components/navigation/UserIcon.tsx +++ b/src/components/navigation/UserIcon.tsx @@ -1,4 +1,5 @@ import { Popover } from "@headlessui/react"; +import { useDatalayer } from "@jhnnsrs/datalayer"; import { useFakts } from "@jhnnsrs/fakts"; import { useHerre } from "@jhnnsrs/herre"; import React, { useState } from "react"; @@ -8,9 +9,8 @@ import { NotificationCenterItem, useNotificationCenter, } from "react-toastify/addons/use-notification-center"; +import { withLok } from "../../lok/LokContext"; import { useProfileQuery } from "../../lok/api/graphql"; -import { withMan } from "../../lok/context"; -import { useMikro } from "../../mikro/MikroContext"; import { useAgent } from "../../rekuest/agent/AgentContext"; import { useAlert } from "../alerter/alerter-context"; @@ -55,7 +55,7 @@ export const UserIcon: React.FC = (props: Props) => { unreadCount, } = useNotificationCenter(); - const { data } = withMan(useProfileQuery)(); + const { data } = withLok(useProfileQuery)(); const [referenceElement, setReferenceElement] = useState(null); const [popperElement, setPopperElement] = useState( @@ -66,7 +66,7 @@ export const UserIcon: React.FC = (props: Props) => { placement: "right-end", }); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); const { alert } = useAlert(); return ( diff --git a/src/components/social/RekuestShare.tsx b/src/components/social/RekuestShare.tsx index 1274f86..94cd5be 100644 --- a/src/components/social/RekuestShare.tsx +++ b/src/components/social/RekuestShare.tsx @@ -1,35 +1,34 @@ +import { useDatalayer } from "@jhnnsrs/datalayer"; import { FieldArray, Form, Formik } from "formik"; import React from "react"; import { Link } from "react-router-dom"; import { notEmpty } from "../../floating/utils"; +import { User } from "../../linker"; +import { withLok } from "../../lok/LokContext"; import { useDetailGroupQuery, useGroupOptionsLazyQuery, useUserOptionsLazyQuery, useUserQuery, } from "../../lok/api/graphql"; -import { withMan } from "../../lok/context"; +import { useMikro } from "../../mikro/MikroContext"; +import { withRekuest } from "../../rekuest"; import { ChangePermissionsMutationVariables, + SharableModels, useChangePermissionsMutation, usePermissionsOfQuery, - SharableModels, } from "../../rekuest/api/graphql"; -import { useMikro, withMikro } from "../../mikro/MikroContext"; -import { SubmitButton } from "../forms/fields/SubmitButton"; -import { withRekuest } from "../../rekuest"; -import { ResponsiveContainerGrid } from "../layout/ResponsiveContainerGrid"; -import { User } from "../../linker"; import { - GraphQLListSearchInput, GraphQLSearchInput, - ListSearchField, ListSearchInput, } from "../forms/fields/SearchInput"; +import { SubmitButton } from "../forms/fields/SubmitButton"; +import { ResponsiveContainerGrid } from "../layout/ResponsiveContainerGrid"; export const PermissionUserInfo = (props: { sub: string }) => { - const { data } = withMan(useUserQuery)({ variables: { id: props.sub } }); - const { s3resolve } = useMikro(); + const { data } = withLok(useUserQuery)({ variables: { id: props.sub } }); + const { s3resolve } = useDatalayer(); return (
@@ -58,7 +57,7 @@ export const PermissionUserInfo = (props: { sub: string }) => { }; export const PermisionGroupInfo = (props: { id: string }) => { - const { data } = withMan(useDetailGroupQuery)({ + const { data } = withLok(useDetailGroupQuery)({ variables: { id: props.id }, }); const { s3resolve } = useMikro(); @@ -91,8 +90,8 @@ export const RekuestShare: React.FC<{ title?: string; object: string; }> = ({ type, object, title }) => { - const [searchGroups] = withMan(useGroupOptionsLazyQuery)(); - const [searchUsers] = withMan(useUserOptionsLazyQuery)(); + const [searchGroups] = withLok(useGroupOptionsLazyQuery)(); + const [searchUsers] = withLok(useUserOptionsLazyQuery)(); const [changePermissions] = withRekuest(useChangePermissionsMutation)(); diff --git a/src/components/social/Share.tsx b/src/components/social/Share.tsx index 6db7211..5b274b4 100644 --- a/src/components/social/Share.tsx +++ b/src/components/social/Share.tsx @@ -1,30 +1,30 @@ +import { useDatalayer } from "@jhnnsrs/datalayer"; import { FieldArray, Form, Formik } from "formik"; import React from "react"; import { Link } from "react-router-dom"; import { notEmpty } from "../../floating/utils"; +import { withLok } from "../../lok/LokContext"; import { useDetailGroupQuery, useGroupOptionsLazyQuery, useUserOptionsLazyQuery, useUserQuery, } from "../../lok/api/graphql"; -import { withMan } from "../../lok/context"; +import { useMikro, withMikro } from "../../mikro/MikroContext"; import { - CommentableModels, ChangePermissionsMutationVariables, + SharableModels, useChangePermissionsMutation, usePermissionsOfQuery, - SharableModels, } from "../../mikro/api/graphql"; -import { useMikro, withMikro } from "../../mikro/MikroContext"; -import { GraphQLSearchInput, SearchInput } from "../forms/fields/SearchInput"; +import { GraphQLSearchInput } from "../forms/fields/SearchInput"; +import { SubmitButton } from "../forms/fields/SubmitButton"; import { SearchSelectInput } from "../forms/fields/search_select_input"; import { SelectInputField } from "../forms/fields/select_input"; -import { SubmitButton } from "../forms/fields/SubmitButton"; export const PermissionUserInfo = (props: { id: string }) => { - const { data } = withMan(useUserQuery)({ variables: { id: props.id } }); - const { s3resolve } = useMikro(); + const { data } = withLok(useUserQuery)({ variables: { id: props.id } }); + const { s3resolve } = useDatalayer(); return (
@@ -53,7 +53,7 @@ export const PermissionUserInfo = (props: { id: string }) => { }; export const PermisionGroupInfo = (props: { id: string }) => { - const { data } = withMan(useDetailGroupQuery)({ + const { data } = withLok(useDetailGroupQuery)({ variables: { id: props.id }, }); const { s3resolve } = useMikro(); @@ -86,8 +86,8 @@ export const Share: React.FC<{ title?: string; object: string; }> = ({ type, object, title }) => { - const [searchGroups] = withMan(useGroupOptionsLazyQuery)(); - const [searchUsers] = withMan(useUserOptionsLazyQuery)(); + const [searchGroups] = withLok(useGroupOptionsLazyQuery)(); + const [searchUsers] = withLok(useUserOptionsLazyQuery)(); const [changePermissions] = withMikro(useChangePermissionsMutation)(); diff --git a/src/constants.tsx b/src/constants.tsx index 98dcac4..5880cc2 100644 --- a/src/constants.tsx +++ b/src/constants.tsx @@ -4,3 +4,5 @@ export const manifest: Manifest = { version: "latest", identifier: "github.io.jhnnsrs.orkestrator", }; + +export const SMART_MODEL_DROP_TYPE = "smart"; diff --git a/src/constants/arnheims.tsx b/src/constants/arnheims.tsx deleted file mode 100644 index c25e0b4..0000000 --- a/src/constants/arnheims.tsx +++ /dev/null @@ -1,47 +0,0 @@ -enum GrantType { - AUTHORIZATION_CODE, - PASSWORD, - IMPLICIT_GRANT, -} - -type Scope = "read" | "write" | "hello"; - -class Arnheim { - host: String; - port: number; - name: String; - grantType: GrantType; - clientSecret: String; - clientId: String; - scopes: Array; - - constructor( - name: String, - host: String, - port: number, - grantType: GrantType, - clientId: String, - clientSecret: String, - scopes: Array - ) { - this.host = host; - this.port = port; - this.name = name; - this.grantType = grantType; - this.clientSecret = clientSecret; - this.clientId = clientId; - this.scopes = scopes; - } -} - -export const arnheims = [ - new Arnheim( - "Local", - "localhost", - 8000, - GrantType.IMPLICIT_GRANT, - "U80GQ1sxCPeJwOjNewzJOVUQoUElIu1rmRFoDWLm", - "dD5vRJE45W7OeLaYfWzNQj7vMwe7rfrlemApFCfflwy4LvAZhL4pj5yk4JW7LvqUqQDTvv6RUDJXvRmZ68l7dsn0A4Rdprga9wqZHtaXbAO3dwYseJRDfGDq0CN4r9pl", - ["read", "write"] - ), -]; diff --git a/src/constants/engines.tsx b/src/constants/engines.tsx deleted file mode 100644 index 96022f2..0000000 --- a/src/constants/engines.tsx +++ /dev/null @@ -1,28 +0,0 @@ -export type NodeEngine = { - engine: string; - description: string; - allowed_nodes: [string]; -}; - -export type NodeEngineMap = { [key: string]: NodeEngine }; - -export const nodeEngines: NodeEngineMap = { - rx: { - engine: "rx", - description: - "This Type of Programming allows for flow oriented Graph constructing, imaging your Data as a Stream", - allowed_nodes: ["*"], - }, - dask: { - engine: "dask", - description: - "This Type of Programming allows for sequentially executing your calls and organize them in a Dask Graph", - allowed_nodes: ["dask"], - }, - auto: { - engine: "auto", - description: - "We will try to infer the best sort of programming for your Graph, (implementation reqults to Rx Right now)", - allowed_nodes: ["*"], - }, -}; diff --git a/src/experimental/provider/provider.tsx b/src/experimental/provider/provider.tsx index 1c82357..8916365 100644 --- a/src/experimental/provider/provider.tsx +++ b/src/experimental/provider/provider.tsx @@ -4,8 +4,8 @@ import React from "react"; import { NestedArray, ZarrArray, openGroup } from "zarr"; import { ArraySelection } from "zarr/types/core/types"; import { withMikro } from "../../mikro/MikroContext"; -import { useRequestQuery } from "../../mikro/api/graphql"; -import { RekuestGuard } from "../../rekuest/RekuestGuard"; +import { useRequestLazyQuery } from "../../mikro/api/graphql"; +import { MikroGuard } from "../../rekuest"; import { ImageView, XArrayContext } from "./context"; import { BasicIndexer } from "./indexing"; import { S3Store } from "./store"; @@ -61,12 +61,15 @@ export type AvailableColormap = (typeof available_color_maps)[number]; export const TrueXArrayProvider: React.FC<{ children: React.ReactNode; }> = (props) => { - const { data, loading, error } = withMikro(useRequestQuery)({}); + const [request] = withMikro(useRequestLazyQuery)({}); const getSelectionAsImageView = async ( path: string, selection: ArraySelection ) => { + let x = await request({}); + let data = x.data; + if (!data?.request) { throw Error("No credentials loaded"); } @@ -234,8 +237,8 @@ export const NoXArrayProvider = ({ export const XArrayProvider = ({ children }: { children: React.ReactNode }) => { return ( - {children}}> + {children}}> {children} - + ); }; diff --git a/src/experimental/render/TwoDOffcanvas.tsx b/src/experimental/render/TwoDOffcanvas.tsx index abae68c..cb4a17e 100644 --- a/src/experimental/render/TwoDOffcanvas.tsx +++ b/src/experimental/render/TwoDOffcanvas.tsx @@ -28,7 +28,11 @@ import { } from "../../mikro/api/graphql"; import { useSettings } from "../../settings/settings-context"; import { ImageView, useXarray } from "../provider/context"; -import { AvailableColormap, available_color_maps } from "../provider/provider"; +import { + AvailableColormap, + XArrayProvider, + available_color_maps, +} from "../provider/provider"; import { dtypeToMinMax } from "../provider/utils"; export interface TwoDProps { representation: CanvasRepresentationFragment; @@ -144,7 +148,7 @@ export const Canvas: React.FC<{ setImageView((image) => imageView); setLoading(false); } catch (e) { - console.error(e) + console.error(e); setError((e as Error).message); } }; @@ -162,8 +166,7 @@ export const Canvas: React.FC<{ setImageData((image) => bitmap); setLoading(false); } catch (e) { - - console.error(e) + console.error(e); setError((e as Error).message); } }; @@ -776,24 +779,26 @@ export const TwoDOffcanvas = ({ 1; return ( - - {({ width, height }) => { - let bwidth = follow == "width" ? width : height * aspectRatio; - let bheight = follow == "width" ? width / aspectRatio : height; - - return ( - - ); - }} - + + + {({ width, height }) => { + let bwidth = follow == "width" ? width : height * aspectRatio; + let bheight = follow == "width" ? width / aspectRatio : height; + + return ( + + ); + }} + + ); }; diff --git a/src/floating/edit/DynamicSidebar.tsx b/src/floating/edit/DynamicSidebar.tsx index da49bef..7da10ed 100644 --- a/src/floating/edit/DynamicSidebar.tsx +++ b/src/floating/edit/DynamicSidebar.tsx @@ -16,10 +16,10 @@ export const DynamicSidebar = () => { useEffect(() => { if (selectedNode) { - console.warn(selectedNode, internalSignal); - const n = nodes.find((n) => n.id === selectedNode); - if (!n) return; - setNode(n); + if (selectedNode != node?.id) { + let node = nodes.find((s) => s?.id == selectedNode); + if (node) setNode(node); + } } else { setNode(null); } diff --git a/src/floating/edit/Edit.tsx b/src/floating/edit/Edit.tsx index c9425b0..41e6a98 100644 --- a/src/floating/edit/Edit.tsx +++ b/src/floating/edit/Edit.tsx @@ -37,7 +37,6 @@ import { DetailTemplateDocument, DetailTemplateQuery, NodeKind, - NodeScope, } from "../../rekuest/api/graphql"; import { Graph } from "../base/Graph"; import { ConnectionMap, FlowNode, NodeTypes } from "../types"; @@ -64,13 +63,11 @@ import { ReturnEditNodeWidget } from "./nodes/generic/ReturnEditNodeWidget"; import dagre from "dagre"; import { useDrop } from "react-dnd"; +import { SMART_MODEL_DROP_TYPE } from "../../constants"; import { FlussKomments } from "../../komment/FlussKomments"; -import { ModuleLayout } from "../../layout/ModuleLayout"; import { PageLayout } from "../../layout/PageLayout"; import { useDialog } from "../../layout/dialog/DialogProvider"; -import FlowDiagramSidebar from "../../pages/flows/workspace/FlowDiagramSidebar"; import { DynamicSidebar } from "./DynamicSidebar"; -import { ExperimentalSidebar } from "./components/ExperimentalSidebar"; import { AskTypeDialog } from "./dialogs/AskTypeDialog"; import { ArkitektFilterNodeWidget } from "./nodes/ArkitektFilterNodeWidget"; import { GraphNodeEditWidget } from "./nodes/GraphNodeEditWidget"; @@ -198,7 +195,7 @@ export const EditRiver: React.FC = ({ ); const [args, setArgs] = useState(flow?.graph.args); const [returns, setReturns] = useState(flow?.graph.returns); - const {ask} = useDialog(); + const { ask } = useDialog(); const [edges, setEdges, onEdgesChange] = useEdgesState( edges_to_flowedges(flow.graph?.edges) @@ -406,18 +403,9 @@ export const EditRiver: React.FC = ({ const [{ isOver, canDrop, type }, dropref] = useDrop(() => { return { - accept: [ - "item:@arkitekt/node", - "list:@arkitekt/node", - "item:@arkitekt/template", - "list:@arkitekt/template", - "item:@arkitekt/graphnode", - "list:@arkitekt/graphnode", - "item:@fluss/reactivetemplate", - "list:@fluss/reactivetemplate", - ], - - drop: (items: { object: string; identifier: string }[], monitor) => { + accept: [SMART_MODEL_DROP_TYPE], + + drop: (items: { id: string; identifier: string }[], monitor) => { if (!monitor.didDrop()) { console.log("Ommitting Parent Drop"); } @@ -433,7 +421,7 @@ export const EditRiver: React.FC = ({ const flowInstance = reactFlowInstance; items.map((i, index) => { - const id = i.object; + const id = i.id; const type = i.identifier; console.log(id, flowInstance, reactFlowBounds, x, y); @@ -454,14 +442,15 @@ export const EditRiver: React.FC = ({ .then(async (event) => { console.log(event); - - - - - if (event.data?.node) { - if (event.data.node.protocols?.find(p => p?.name == "predicate")) { - const answer = await ask(AskTypeDialog, {filter: ["filter", "map"]}) + if ( + event.data.node.protocols?.find( + (p) => p?.name == "predicate" + ) + ) { + const answer = await ask(AskTypeDialog, { + filter: ["filter", "map"], + }); if (answer.type == "filter") { let id = "arkid-" + uuidv4(); let node: FlowNode = { @@ -473,7 +462,8 @@ export const EditRiver: React.FC = ({ instream: [ event?.data?.node?.args ?.filter( - (x) => !x?.nullable && x?.default == undefined + (x) => + !x?.nullable && x?.default == undefined ) // by default, all nullable and default values are optional so not part of stream .filter(notEmpty) .map(rekuestPortToFluss) || [], @@ -488,7 +478,8 @@ export const EditRiver: React.FC = ({ outstream: [ event?.data?.node?.args ?.filter( - (x) => !x?.nullable && x?.default == undefined + (x) => + !x?.nullable && x?.default == undefined ) // by default, all nullable and default values are optional so not part of stream .filter(notEmpty) .map(rekuestPortToFluss) || [], @@ -496,55 +487,52 @@ export const EditRiver: React.FC = ({ constream: [], name: event.data?.node?.name || "no-name", hash: event.data?.node?.hash || "", - kind: event.data?.node?.kind || NodeKind.Generator, + kind: + event.data?.node?.kind || NodeKind.Generator, }, position: position, }; addArkitekt(node); return; } - } + let id = "arkid-" + uuidv4(); + let node: FlowNode = { + id: id, + type: "ArkitektNode", + dragHandle: ".custom-drag-handle", + data: { + __typename: "ArkitektNode", + instream: [ + event?.data?.node?.args + ?.filter( + (x) => !x?.nullable && x?.default == undefined + ) // by default, all nullable and default values are optional so not part of stream + .filter(notEmpty) + .map(rekuestPortToFluss) || [], + ], + mapStrategy: MapStrategy.Map, + allowLocal: false, + assignTimeout: 100000, + yieldTimeout: 100000, + reserveTimeout: 100000, + maxRetries: 3, + retryDelay: 2000, + outstream: [ + event?.data?.node?.returns + ?.filter(notEmpty) + .map(rekuestPortToFluss) || [], + ], + constream: [], + name: event.data?.node?.name || "no-name", + hash: event.data?.node?.hash || "", + kind: event.data?.node?.kind || NodeKind.Generator, + }, + position: position, + }; - // two paths according to node scope - if (event.data.node.scope == NodeScope.Global) { - let id = "arkid-" + uuidv4(); - let node: FlowNode = { - id: id, - type: "ArkitektNode", - dragHandle: ".custom-drag-handle", - data: { - __typename: "ArkitektNode", - instream: [ - event?.data?.node?.args - ?.filter( - (x) => !x?.nullable && x?.default == undefined - ) // by default, all nullable and default values are optional so not part of stream - .filter(notEmpty) - .map(rekuestPortToFluss) || [], - ], - mapStrategy: MapStrategy.Map, - allowLocal: false, - assignTimeout: 100000, - yieldTimeout: 100000, - reserveTimeout: 100000, - maxRetries: 3, - retryDelay: 2000, - outstream: [ - event?.data?.node?.returns - ?.filter(notEmpty) - .map(rekuestPortToFluss) || [], - ], - constream: [], - name: event.data?.node?.name || "no-name", - hash: event.data?.node?.hash || "", - kind: event.data?.node?.kind || NodeKind.Generator, - }, - position: position, - }; - addArkitekt(node); - } + addArkitekt(node); } }); } @@ -713,83 +701,60 @@ export const EditRiver: React.FC = ({ flow, }} > - , + }, { label: "Nodes", key: "nodes", content: , }, { - label: "Versions", - key: "versions", + label: "Social", + key: "social", content: ( - <> - {flow?.workspace?.id && ( - +
+ {flow.workspace?.id && ( + )} - - ), - }, - { - label: "Experimental", - key: "experimental", - content: ( - <>{flow?.workspace?.id && } +
), }, ]} + actions={} > - , - }, - { - label: "Social", - key: "social", - content: ( -
- {flow.workspace?.id && ( - - )} -
- ), - }, - ]} - actions={} +
-
-
- setSelectedNode(undefined)} - onDragOver={onDragOver} - nodes={nodes} - edges={edges} - elementsSelectable={true} - onConnect={onConnect} - nodeTypes={nodeTypes} - edgeTypes={edgeTypes} - onNodeClick={(e, n) => setSelectedNode(n.id)} - onNodesChange={onNodesChange} - onEdgesChange={onEdgesChange} - onInit={(e) => setReactFlowInstance(e)} - fitView - attributionPosition="top-right" - > -
+
+ setSelectedNode(undefined)} + onDragOver={onDragOver} + nodes={nodes} + edges={edges} + elementsSelectable={true} + onConnect={onConnect} + nodeTypes={nodeTypes} + edgeTypes={edgeTypes} + onNodeClick={(e, n) => setSelectedNode(n.id)} + onNodesChange={onNodesChange} + onEdgesChange={onEdgesChange} + onInit={(e) => setReactFlowInstance(e)} + fitView + attributionPosition="top-right" + >
- - +
+ ); }; diff --git a/src/floating/edit/EditActions.tsx b/src/floating/edit/EditActions.tsx index d3736af..86a67cf 100644 --- a/src/floating/edit/EditActions.tsx +++ b/src/floating/edit/EditActions.tsx @@ -7,8 +7,8 @@ import { useDialog } from "../../layout/dialog/DialogProvider"; import { Node } from "../../linker"; import { withRekuest } from "../../rekuest"; import { ReservationStatus, useNodesQuery } from "../../rekuest/api/graphql"; -import { useRequester } from "../../rekuest/postman/requester/requester-context"; -import { useReserver } from "../../rekuest/postman/reserver/reserver-context"; +import { useRequester } from "../../rekuest/providers/requester/requester-context"; +import { useReserver } from "../../rekuest/providers/reserver/reserver-context"; import { useEditRiver } from "./context"; export interface EditActionsProps { diff --git a/src/floating/edit/components/EditSidebar.tsx b/src/floating/edit/components/EditSidebar.tsx index 1b64acf..c52a0ef 100644 --- a/src/floating/edit/components/EditSidebar.tsx +++ b/src/floating/edit/components/EditSidebar.tsx @@ -7,13 +7,14 @@ import { useReactiveTemplatesQuery, } from "../../../fluss/api/graphql"; import { withFluss } from "../../../fluss/fluss"; -import { DashboardSearchFilter } from "../../../pages/dashboard/DashboardSearch"; import { withRekuest } from "../../../rekuest/RekuestContext"; import { NodeListItemFragment, NodeScope, + NodesQueryVariables, useNodesQuery, } from "../../../rekuest/api/graphql"; +import { NodeSearchFilter } from "../../../rekuest/components/searches/NodeSearchFilter"; import { SmartModel } from "../../../rekuest/selection/SmartModel"; import { ChangeSubmitHelper } from "../../../rekuest/ui/helpers/ChangeSubmitter"; import { notEmpty } from "../../utils"; @@ -169,19 +170,11 @@ export const EditSidebar: React.FC = (props) => { useNodesQuery )({ variables: { - scopes: [NodeScope.Global], - }, - }); - - const { data: localNodes, refetch: refetchLocalNodes } = withRekuest( - useNodesQuery - )({ - variables: { - restrict: props.flow.restrict, scopes: [ NodeScope.BridgeGlobalToLocal, NodeScope.Local, NodeScope.BridgeLocalToGlobal, + NodeScope.Global, ], }, }); @@ -190,18 +183,19 @@ export const EditSidebar: React.FC = (props) => { useReactiveTemplatesQuery )(); - const [filter, setFilter] = React.useState({ search: "" }); + const [filter, setFilter] = React.useState({ + search: "", + }); useEffect(() => { refetchArkiNodes(filter); - refetchLocalNodes(filter); refetchReactiveNodes(filter); }, [filter]); return ( <>
- diff --git a/src/floating/edit/components/ExperimentalSidebar.tsx b/src/floating/edit/components/ExperimentalSidebar.tsx deleted file mode 100644 index f479a63..0000000 --- a/src/floating/edit/components/ExperimentalSidebar.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { Field, Form, Formik, FormikHelpers } from "formik"; -import { Maybe } from "graphql/jsutils/Maybe"; -import React, { useEffect } from "react"; -import { FlowFragment } from "../../../fluss/api/graphql"; -import { withRekuest } from "../../../rekuest/RekuestContext"; -import { - DisplayTemplateFragment, - NodeScope, - useNodeTemplatesQuery, -} from "../../../rekuest/api/graphql"; -import { SmartModel } from "../../../rekuest/selection/SmartModel"; -import { ChangeSubmitHelper } from "../../../rekuest/ui/helpers/ChangeSubmitter"; - -interface NodeListProps { - templates: Maybe[]; -} - -export const LocalItem = ({ - template, -}: { - template: Maybe; -}) => { - return ( - - `rounded-md dark:bg-slate-900 dark:text-slate-50 w-full hover:overflow-hidden p-2 shadow-md shadow-blue-700/20 bg-white hover:text-white hover:bg-gray-800 border-slate-500 border cursor-pointer ${ - isDragging && "border-primary-300" - }` - } - > -
-
- {template?.node?.name} @ {template?.interface} -
-

{template?.node?.description}

-
-
- ); -}; - -export const GraphItem = () => { - return ( - - `rounded-md dark:bg-slate-900 dark:text-slate-50 w-full hover:overflow-hidden p-2 shadow-md shadow-blue-700/20 bg-white hover:text-white hover:bg-gray-800 border-slate-500 border cursor-pointer ${ - isDragging && "border-primary-300" - }` - } - > -
-
GraphNode
-
-
- ); -}; - -export const LocalTemplate: React.FC = ({ templates }) => { - return ( -
- {templates?.length > 0 && ( -
- Local Nodes -
- )} - {templates?.map((template) => ( - - ))} -
- ); -}; - -interface NodeFilterBoxProps { - onFilterChanged: (values: NodeFilterValues) => any; - className?: string; - placeholder?: string; -} - -interface NodeFilterValues { - search: string; -} - -export const NodeFilterBox: React.FC = ({ - onFilterChanged, - className, - placeholder, -}) => { - return ( - - ) => { - console.log(values); - onFilterChanged(values); - setSubmitting(false); - }} - > - {(formik) => ( -
- - - - )} -
- ); -}; - -interface EditSidebarProps { - flow: FlowFragment; -} - -export const ExperimentalSidebar: React.FC = (props) => { - if (!props.flow) return null; - - const { data: localNodes, refetch: refetchLocalNodes } = withRekuest( - useNodeTemplatesQuery - )({ - variables: { - scopes: [ - NodeScope.BridgeGlobalToLocal, - NodeScope.Local, - NodeScope.BridgeLocalToGlobal, - ], - }, - }); - - const [filter, setFilter] = React.useState({ search: "" }); - - useEffect(() => { - refetchLocalNodes(filter); - }, [filter]); - - return ( - <> -
- setFilter(filter)} - className="w-full p-3 rounded-md shadow-lg dark:bg-slate-200 dark:text-black" - /> -
-
- - {localNodes?.templates && ( - - )} -
- - ); -}; diff --git a/src/floating/edit/logic/connect.tsx b/src/floating/edit/logic/connect.tsx index fdde9c2..d5d62d0 100644 --- a/src/floating/edit/logic/connect.tsx +++ b/src/floating/edit/logic/connect.tsx @@ -380,6 +380,8 @@ export const to_reactive: Connector = ({ new_outstream = [sourceStream]; } + + if ( [ReactiveImplementationModelInput.Gate].includes( targetNode.data.implementation diff --git a/src/floating/edit/sidebars/ArkitektNodeSidebar.tsx b/src/floating/edit/sidebars/ArkitektNodeSidebar.tsx index 0365c8a..0980eb1 100644 --- a/src/floating/edit/sidebars/ArkitektNodeSidebar.tsx +++ b/src/floating/edit/sidebars/ArkitektNodeSidebar.tsx @@ -9,6 +9,7 @@ import { useHashReservableTemplatesQuery, } from "../../../rekuest/api/graphql"; import { ConstantsForm } from "../../../rekuest/components/ConstantsForm"; +import { NodeDescription } from "../../../rekuest/components/NodeDescription"; import { ReserveParamsField } from "../../../rekuest/components/ReserveParamsField"; import { ChangeSubmitHelper } from "../../../rekuest/ui/helpers/ChangeSubmitter"; import { ArkitektNodeData, FlowNode } from "../../types"; @@ -56,10 +57,6 @@ export const ArkitektNodeSidebar = (
{node_data?.node?.name}
-
- {" "} - {node_data?.node?.description} -
Constants
{node_data?.node?.id && ( @@ -74,6 +71,20 @@ export const ArkitektNodeSidebar = ( }); }} initial={props.node.data.defaults} + prependChildren={(formikProps) => { + return ( + <> +
+ {node_data?.node?.description != undefined && ( + + )} +
+ + ); + }} /> )}
diff --git a/src/floating/edit/sidebars/CanvasSidebar.tsx b/src/floating/edit/sidebars/CanvasSidebar.tsx index 77b7979..967395e 100644 --- a/src/floating/edit/sidebars/CanvasSidebar.tsx +++ b/src/floating/edit/sidebars/CanvasSidebar.tsx @@ -1,12 +1,82 @@ +import { FittingResponsiveContainerGrid } from "../../../components/layout/ResponsiveContainerGrid"; +import { SectionTitle } from "../../../layout/SectionTitle"; +import { useRequesterMate } from "../../../mates/reservation/useRequesterMate"; +import { useTemplateActionMate } from "../../../mates/template/useTemplateActionsMate"; +import { withRekuest } from "../../../rekuest"; +import { + useReservableTemplatesQuery, + useThisFilteredReservationsQuery, +} from "../../../rekuest/api/graphql"; +import { ReservationCard } from "../../../rekuest/components/cards/ReservationCard"; +import { TemplateCard } from "../../../rekuest/components/cards/TemplateCard"; +import { notEmpty } from "../../utils"; import { useEditRiver } from "../context"; export const CanvasSidebar = (props: {}) => { const { flow } = useEditRiver(); + const { data: resdata, error: reserror } = withRekuest( + useThisFilteredReservationsQuery + )({ + fetchPolicy: "network-only", + variables: { + templateParams: [ + { + key: "flow", + value: flow.id, + }, + ], + }, + }); + + const { data: tempdata, error } = withRekuest(useReservableTemplatesQuery)({ + fetchPolicy: "network-only", + variables: { + templateParams: [ + { + key: "flow", + value: flow.id, + }, + ], + }, + }); + + const templateMate = useTemplateActionMate(); + const resMate = useRequesterMate(); + return (
-
Flow
-
{flow.id}
+
{flow.name}
+
{flow.description}
+ + Deployed on + + {tempdata?.reservableTemplates?.filter(notEmpty).map((temp, index) => ( + + ))} + +
+ Used by + + {resdata?.reservations?.filter(notEmpty).map((res, index) => ( + + ))} + +
+ {error &&
{error.message}
} + {reserror &&
{reserror.message}
}
); }; diff --git a/src/floating/utils.tsx b/src/floating/utils.tsx index b30c1ff..a2a21fd 100644 --- a/src/floating/utils.tsx +++ b/src/floating/utils.tsx @@ -36,7 +36,9 @@ export const flussPortChildToStreamItem = ( identifier: port.identifier, nullable: port.nullable, scope: port.scope, - variants: port?.variants?.filter(notEmpty).map(x => flussPortChildToStreamItem(x)), + variants: port?.variants + ?.filter(notEmpty) + .map((x) => flussPortChildToStreamItem(x)), child: port.child && flussPortChildToStreamItem(port.child), }; }; @@ -48,7 +50,9 @@ export const flussPortToStreamItem = (port: PortFragment): StreamItem => { identifier: port.identifier, nullable: port.nullable, scope: port.scope, - variants: port?.variants?.filter(notEmpty).map(x => flussPortChildToStreamItem(x)), + variants: port?.variants + ?.filter(notEmpty) + .map((x) => flussPortChildToStreamItem(x)), child: port.child && flussPortChildToStreamItem(port.child), }; }; @@ -81,10 +85,10 @@ export const rekuestChildPortToFluss = ( nullable: port?.nullable || false, child: port?.child && - rekuestChildPortToFluss(port?.child as RekuestChildPortFragment), - variants: - port?.variants?.filter(notEmpty).map( p => - rekuestChildPortToFluss(p as RekuestChildPortFragment)), //TODO: manage this//TODO: manage this + rekuestChildPortToFluss(port?.child as RekuestChildPortFragment), + variants: port?.variants + ?.filter(notEmpty) + .map((p) => rekuestChildPortToFluss(p as RekuestChildPortFragment)), //TODO: manage this//TODO: manage this }; }; @@ -111,7 +115,9 @@ export const rekuestPortToFluss = (port: RekuestPortFragment): PortFragment => { label: port.label, assignWidget: cleanedAssign, returnWidget: cleanedReturn, - variants: port?.variants?.filter(notEmpty).map((x) => rekuestChildPortToFluss(x)), + variants: port?.variants + ?.filter(notEmpty) + .map((x) => rekuestChildPortToFluss(x)), child: port?.child && rekuestChildPortToFluss(port?.child), }; }; @@ -135,6 +141,15 @@ export function noTypename(obj: T): T { return z; } +export function keyInObject( + key: string, + obj: any +): obj is { + [key: string]: any; +} { + return obj && key in obj; +} + export const nodes_to_flownodes = ( nodes: (FlowNodeFragment | null | undefined)[] | null | undefined ): FlowNode[] => { diff --git a/src/fluss/FlussModule.tsx b/src/fluss/FlussModule.tsx new file mode 100644 index 0000000..f3c50a5 --- /dev/null +++ b/src/fluss/FlussModule.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import { Route, Routes } from "react-router"; +import { ModuleLayout } from "../layout/ModuleLayout"; +import { RunScreen } from "../pages/detail/RunScreen"; +import { FlussGuard } from "./guard"; +import FlowHome from "./pages/FlowHome"; +import { FlowTimeline } from "./pages/timelines/FlowTimeline"; +import { FlowDiagram } from "./pages/workspace/FlowDiagram"; +import { FlowDiagramFlow } from "./pages/workspace/FlowDiagramFlow"; +import { FlowDiagramHome } from "./pages/workspace/FlowDiagramHome"; +import SidePane from "./panes/FlowSidebar"; +interface Props {} + +export const FlussModule: React.FC = (props) => { + return ( + Loading}> + , + }, + ]} + > + + } /> + }> + } /> + + } /> + } /> + } /> + } /> + + + + ); +}; + +export default FlussModule; diff --git a/src/fluss/api/graphql.ts b/src/fluss/api/graphql.ts index 25c2bf0..b3ea66d 100644 --- a/src/fluss/api/graphql.ts +++ b/src/fluss/api/graphql.ts @@ -1291,6 +1291,10 @@ export enum ReactiveImplementationModelInput { Chunk = 'CHUNK', /** COMBINELATEST (Combine values with latest value from each stream) */ Combinelatest = 'COMBINELATEST', + /** DELAY (Delay the data) */ + Delay = 'DELAY', + /** DELAY_UNTIL (Delay the data until signal is send) */ + DelayUntil = 'DELAY_UNTIL', /** DIVIDE (Divide the data with a number) */ Divide = 'DIVIDE', /** ENSURE (Ensure the data (discards None in the stream)) */ diff --git a/src/fluss/components/dialogs/DeployFlowDialog.tsx b/src/fluss/components/dialogs/DeployFlowDialog.tsx index 31bc94a..e027d01 100644 --- a/src/fluss/components/dialogs/DeployFlowDialog.tsx +++ b/src/fluss/components/dialogs/DeployFlowDialog.tsx @@ -1,41 +1,38 @@ import { useAlert } from "../../../components/alerter/alerter-context"; +import { FittingResponsiveContainerGrid } from "../../../components/layout/ResponsiveContainerGrid"; import { notEmpty } from "../../../floating/utils"; import { Submit } from "../../../layout/dialog/DialogProvider"; import { TwDialog } from "../../../layout/dialog/TwDialog"; import { useDetailClientQuery } from "../../../lok/api/graphql"; import { ClientCard } from "../../../lok/components/cards/ClientCard"; -import { withMan } from "../../../lok/man"; +import { withLok } from "../../../lok/LokContext"; import { withRekuest } from "../../../rekuest"; import { ListProvisionFragment, useDeployReservationsQuery, } from "../../../rekuest/api/graphql"; import { ReservationPulse } from "../../../rekuest/components/generic/StatusPulse"; -import { useRequester } from "../../../rekuest/postman/requester/requester-context"; -import { useReserver } from "../../../rekuest/postman/reserver/reserver-context"; +import { useRequester } from "../../../rekuest/providers/requester/requester-context"; +import { useReserver } from "../../../rekuest/providers/reserver/reserver-context"; export const ClientX = (props: { id: string }) => { - const { data } = withMan(useDetailClientQuery)({ + const { data } = withLok(useDetailClientQuery)({ variables: { clientId: props.id }, }); - return ( -
- {data?.client && } -
- ); + return data?.client ? : <>....; }; export const ResCard = ({ res, flow }: { res: any; flow: string }) => { const { assign } = useRequester(); - const { data } = withMan(useDetailClientQuery)({ + const { data } = withLok(useDetailClientQuery)({ variables: { id: res.waiter?.clientId }, }); return (
{ assign({ reservation: res, @@ -47,13 +44,11 @@ export const ResCard = ({ res, flow }: { res: any; flow: string }) => {
{res?.node?.name || res?.title}
-
+ {res.provisions.map((provision: ListProvisionFragment) => ( -
- -
+ ))} -
+
); }; @@ -94,13 +89,13 @@ export const DeployFlowDialog = (props: Submit<{}> & { flow: string }) => { used to run your worfklow.
{data?.reservations && data?.reservations.length > 0 ? ( -
- {data?.reservations?.filter(notEmpty).map((res) => ( -
- -
+ + {data?.reservations?.filter(notEmpty).map((res, index) => ( + ))} -
+ ) : (
You have not registered any apps that can be used to run your diff --git a/src/fluss/graphql.schema.json b/src/fluss/graphql.schema.json index 55e4a92..d6dcfd3 100644 --- a/src/fluss/graphql.schema.json +++ b/src/fluss/graphql.schema.json @@ -9906,6 +9906,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "DELAY", + "description": "DELAY (Delay the data)", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DELAY_UNTIL", + "description": "DELAY_UNTIL (Delay the data until signal is send)", + "isDeprecated": false, + "deprecationReason": null + }, { "name": "DIVIDE", "description": "DIVIDE (Divide the data with a number)", diff --git a/src/pages/flows/FlowAssignation.tsx b/src/fluss/pages/FlowAssignation.tsx similarity index 100% rename from src/pages/flows/FlowAssignation.tsx rename to src/fluss/pages/FlowAssignation.tsx diff --git a/src/pages/flows/FlowHome.tsx b/src/fluss/pages/FlowHome.tsx similarity index 100% rename from src/pages/flows/FlowHome.tsx rename to src/fluss/pages/FlowHome.tsx diff --git a/src/pages/flows/FlowHomeSidebar.tsx b/src/fluss/pages/FlowHomeSidebar.tsx similarity index 100% rename from src/pages/flows/FlowHomeSidebar.tsx rename to src/fluss/pages/FlowHomeSidebar.tsx diff --git a/src/pages/flows/flows/FlowFlowsFlow.tsx b/src/fluss/pages/flows/FlowFlowsFlow.tsx similarity index 100% rename from src/pages/flows/flows/FlowFlowsFlow.tsx rename to src/fluss/pages/flows/FlowFlowsFlow.tsx diff --git a/src/pages/flows/runs/RunSidebar.tsx b/src/fluss/pages/runs/RunSidebar.tsx similarity index 100% rename from src/pages/flows/runs/RunSidebar.tsx rename to src/fluss/pages/runs/RunSidebar.tsx diff --git a/src/pages/flows/runs/RunsHome.tsx b/src/fluss/pages/runs/RunsHome.tsx similarity index 100% rename from src/pages/flows/runs/RunsHome.tsx rename to src/fluss/pages/runs/RunsHome.tsx diff --git a/src/pages/flows/timelines/FlowTimeline.tsx b/src/fluss/pages/timelines/FlowTimeline.tsx similarity index 100% rename from src/pages/flows/timelines/FlowTimeline.tsx rename to src/fluss/pages/timelines/FlowTimeline.tsx diff --git a/src/pages/flows/workspace/FlowDiagram.tsx b/src/fluss/pages/workspace/FlowDiagram.tsx similarity index 100% rename from src/pages/flows/workspace/FlowDiagram.tsx rename to src/fluss/pages/workspace/FlowDiagram.tsx diff --git a/src/pages/flows/workspace/FlowDiagramFlow.tsx b/src/fluss/pages/workspace/FlowDiagramFlow.tsx similarity index 100% rename from src/pages/flows/workspace/FlowDiagramFlow.tsx rename to src/fluss/pages/workspace/FlowDiagramFlow.tsx diff --git a/src/pages/flows/workspace/FlowDiagramHome.tsx b/src/fluss/pages/workspace/FlowDiagramHome.tsx similarity index 100% rename from src/pages/flows/workspace/FlowDiagramHome.tsx rename to src/fluss/pages/workspace/FlowDiagramHome.tsx diff --git a/src/pages/flows/workspace/FlowDiagramSidebar.tsx b/src/fluss/pages/workspace/FlowDiagramSidebar.tsx similarity index 93% rename from src/pages/flows/workspace/FlowDiagramSidebar.tsx rename to src/fluss/pages/workspace/FlowDiagramSidebar.tsx index 952938d..44fd087 100644 --- a/src/pages/flows/workspace/FlowDiagramSidebar.tsx +++ b/src/fluss/pages/workspace/FlowDiagramSidebar.tsx @@ -1,17 +1,16 @@ import * as React from "react"; import Timestamp from "react-timestamp"; -import { useNodesQuery } from "../../../rekuest/api/graphql"; -import { usePostman } from "../../../rekuest/postman/graphql/postman-context"; -import { useRequester } from "../../../rekuest/postman/requester/requester-context"; import { notEmpty } from "../../../floating/utils"; import { ListFlowFragment, useSearchFlowsQuery, } from "../../../fluss/api/graphql"; import { withFluss } from "../../../fluss/fluss"; -import { useFluss } from "../../../fluss/fluss-context"; import { Flow } from "../../../linker"; import { withRekuest } from "../../../rekuest"; +import { useNodesQuery } from "../../../rekuest/api/graphql"; +import { usePostman } from "../../../rekuest/providers/legacy/postman-context"; +import { useRequester } from "../../../rekuest/providers/requester/requester-context"; interface IDataSidebarProps { workspace: string; diff --git a/src/pages/flows/FlowSidebar.tsx b/src/fluss/panes/FlowSidebar.tsx similarity index 86% rename from src/pages/flows/FlowSidebar.tsx rename to src/fluss/panes/FlowSidebar.tsx index 5a1366c..a06409e 100644 --- a/src/pages/flows/FlowSidebar.tsx +++ b/src/fluss/panes/FlowSidebar.tsx @@ -4,10 +4,10 @@ import { notEmpty } from "../../floating/utils"; import { FlussGlobalSearchQueryVariables, useFlussGlobalSearchQuery, -} from "../../fluss/api/graphql"; -import { WorkspaceCard } from "../../fluss/components/cards/WorkspaceCard"; -import { FlussSearch } from "../../fluss/components/FlussSearch"; -import { withFluss } from "../../fluss/fluss"; +} from "../api/graphql"; +import { WorkspaceCard } from "../components/cards/WorkspaceCard"; +import { FlussSearch } from "../components/FlussSearch"; +import { withFluss } from "../fluss"; interface IDataSidebarProps {} diff --git a/src/fluss/ward.tsx b/src/fluss/ward.tsx index 8264661..1148919 100644 --- a/src/fluss/ward.tsx +++ b/src/fluss/ward.tsx @@ -1,13 +1,11 @@ import { gql } from "@apollo/client"; import React, { useEffect } from "react"; -import { useRekuest } from "../rekuest/RekuestContext"; import { useWidgetRegistry } from "../rekuest/widgets/widget-context"; import { useFluss } from "./fluss-context"; export const FlussWard: React.FC<{ key?: string; fallback?: React.ReactNode; - children: React.ReactNode; }> = ({ key, children, fallback }) => { const { client } = useFluss(); const { registry } = useWidgetRegistry(); @@ -33,5 +31,5 @@ export const FlussWard: React.FC<{ } }, [client, registry]); - return <>{children}; + return <>; }; diff --git a/src/komment/display/Mention.tsx b/src/komment/display/Mention.tsx index db4aa6c..4c58418 100644 --- a/src/komment/display/Mention.tsx +++ b/src/komment/display/Mention.tsx @@ -1,14 +1,13 @@ -import { getDefaultSmartModel, User } from "../../linker"; +import { User } from "../../linker"; import { useUserQuery } from "../../lok/api/graphql"; -import { withMan } from "../../lok/man"; -import { AdditionalMate } from "../../rekuest/postman/mater/mater-context"; +import { withLok } from "../../lok/LokContext"; import { MentionType } from "../types"; export const Mention = (props: { element: MentionType }) => { if (!props.element.user.sub) { return <>Illl configured; } - const { data, error } = withMan(useUserQuery)({ + const { data, error } = withLok(useUserQuery)({ variables: { id: props.element.user.sub }, }); diff --git a/src/komment/edit/CommentEdit.tsx b/src/komment/edit/CommentEdit.tsx index fa11aff..37e2d98 100644 --- a/src/komment/edit/CommentEdit.tsx +++ b/src/komment/edit/CommentEdit.tsx @@ -1,18 +1,18 @@ import { useCallback, useEffect, useRef, useState } from "react"; -import { createEditor, Editor, Node, Range, Transforms } from "slate"; +import { BiBold, BiCode, BiItalic, BiUnderline } from "react-icons/bi"; +import { TiTick } from "react-icons/ti"; +import { Editor, Node, Range, Transforms, createEditor } from "slate"; import { Editable, ReactEditor, Slate, useSlate, withReact } from "slate-react"; +import { withLok } from "../../lok/LokContext"; import { useUserOptionsLazyQuery } from "../../lok/api/graphql"; -import { withMan } from "../../lok/context"; import { CreateCommentFunc, KommentEditor } from "../types"; import { - insertMention, KommentElement, KommentLeaf, Portal, + insertMention, withMentions, } from "./shared"; -import { BiBold, BiItalic, BiUnderline, BiCode } from "react-icons/bi"; -import { TiTick } from "react-icons/ti"; export type ICommentEditProps = { id: string; @@ -35,7 +35,7 @@ export type CommentEditProps = { }; const marks = ["bold", "italic", "underline", "code"] as const; -type Mark = typeof marks[number]; +type Mark = (typeof marks)[number]; const toggleMark = (editor: KommentEditor, format: Mark) => { const isActive = isMarkActive(editor, format); @@ -82,7 +82,7 @@ export const CommentEdit = ({ }: CommentEditProps) => { const [editor] = useState(() => withMentions(withReact(createEditor()))); - const [searchUser, data] = withMan(useUserOptionsLazyQuery)(); + const [searchUser, data] = withLok(useUserOptionsLazyQuery)(); const ref = useRef(null); const [target, setTarget] = useState(); diff --git a/src/komment/edit/MentionEdit.tsx b/src/komment/edit/MentionEdit.tsx index 1a10f60..db18fa1 100644 --- a/src/komment/edit/MentionEdit.tsx +++ b/src/komment/edit/MentionEdit.tsx @@ -1,7 +1,6 @@ import { useFocused, useSelected } from "slate-react"; -import { User } from "../../linker"; +import { withLok } from "../../lok/LokContext"; import { useUserQuery } from "../../lok/api/graphql"; -import { withMan } from "../../lok/man"; import { ElementRenderProps } from "../types"; export const MentionEdit = ({ @@ -16,7 +15,7 @@ export const MentionEdit = ({ const focused = useFocused(); console.log(element); - const { data, error } = withMan(useUserQuery)({ + const { data, error } = withLok(useUserQuery)({ variables: { id: element.user }, }); diff --git a/src/komment/edit/ReplyTo.tsx b/src/komment/edit/ReplyTo.tsx index 2553dbb..511aacb 100644 --- a/src/komment/edit/ReplyTo.tsx +++ b/src/komment/edit/ReplyTo.tsx @@ -1,18 +1,10 @@ import { useCallback, useEffect, useRef, useState } from "react"; -import { - BaseRange, - createEditor, - Editor, - Node, - Range, - Transforms, -} from "slate"; +import ReactDOM from "react-dom"; +import { Editor, Range, Transforms, createEditor } from "slate"; import { Editable, ReactEditor, Slate, withReact } from "slate-react"; +import { withLok } from "../../lok/LokContext"; import { useUserOptionsLazyQuery } from "../../lok/api/graphql"; -import { withMan } from "../../lok/context"; -import ReactDOM from "react-dom"; import { - CreateCommentFunc, DescendendInput, ElementRenderProps, KommentEditor, @@ -20,7 +12,6 @@ import { ReplyToFunc, } from "../types"; import { MentionEdit } from "./MentionEdit"; -import { DOMRange } from "slate-react/dist/utils/dom"; const Element = (props: ElementRenderProps) => { const { element, ...restprops } = props; @@ -88,7 +79,7 @@ export const ReplyTo = ({ }: CommentEditProps) => { const [editor] = useState(() => withMentions(withReact(createEditor()))); - const [searchUser, data] = withMan(useUserOptionsLazyQuery)(); + const [searchUser, data] = withLok(useUserOptionsLazyQuery)(); const ref = useRef(null); const [target, setTarget] = useState(); diff --git a/src/layout/PaginatedList.tsx b/src/layout/PaginatedList.tsx new file mode 100644 index 0000000..d45cf75 --- /dev/null +++ b/src/layout/PaginatedList.tsx @@ -0,0 +1,146 @@ +import React, { ReactNode, useEffect, useState } from "react"; +import { BiRefresh } from "react-icons/bi"; +import { BsCaretLeft, BsCaretRight } from "react-icons/bs"; +import { ResponsiveContainerGrid } from "../components/layout/ResponsiveContainerGrid"; +import { notEmpty } from "../floating/utils"; + +export const SectionTitle = (props: { + children: React.ReactNode; + right?: React.ReactNode; + onClick?: () => void; +}) => { + return ( +
+
{props.children}
+ {props.right &&
{props.right}
} +
+ ); +}; + +export const Refetcher = (props: { onClick: () => Promise }) => { + const [refetching, setRefetching] = useState(false); + + const onClick = async () => { + setRefetching(true); + await props.onClick(); + setRefetching(false); + }; + + return ( + + ); +}; + +export const Offsetter = ({ + offset, + setOffset, + step, + array, +}: { + offset: number; + setOffset: React.Dispatch>; + step: number; + array?: any[] | undefined | null; +}) => ( + <> + {offset != 0 && ( + + )} + {array && array.length == step && ( + + )} + +); + +export const ConditionalRender = ({ + array, + loading, + children, +}: { + array?: any[] | undefined | null; + loading?: boolean; + children: ReactNode; +}) => { + return <>{array && array.length > 0 && children}; +}; + +export const PaginatedList = ({ + title, + loading, + array, + actions, + children, + refetch, + limit = 20, +}: { + title: React.ReactNode; + loading?: boolean; + children: (item: T, index: number) => ReactNode; + array: (T | null | undefined)[] | null | undefined; + limit?: number; + actions?: React.ReactNode; + refetch?: (values: { + pagination: { limit: number; offset: number }; + }) => Promise; +}) => { + const [offset, setOffset] = useState(0); + + useEffect(() => { + if (refetch) { + refetch({ pagination: { limit: limit, offset: offset } }); + } + }, [offset, limit]); + + return ( + <> + {array && (array.length > 0 || offset > 0) && ( + <> + + + {refetch && ( + + refetch({ pagination: { limit: limit, offset: offset } }) + } + /> + )} + {actions} +
+ } + > + {title} + + + {array?.filter(notEmpty).map(children)} + + + )} + + ); +}; diff --git a/src/layout/dialog/Dialog.tsx b/src/layout/dialog/Dialog.tsx new file mode 100644 index 0000000..cb2f43c --- /dev/null +++ b/src/layout/dialog/Dialog.tsx @@ -0,0 +1,7 @@ +import { useDialog } from "./DialogProvider"; + +export const DialogDisplay = () => { + const { component } = useDialog(); + + return component ? <>{component} : <>; +}; diff --git a/src/layout/dialog/DialogProvider.tsx b/src/layout/dialog/DialogProvider.tsx index 862b9fa..16074cc 100644 --- a/src/layout/dialog/DialogProvider.tsx +++ b/src/layout/dialog/DialogProvider.tsx @@ -1,15 +1,6 @@ import { Dialog, Transition } from "@headlessui/react"; import CancelablePromise from "cancelable-promise"; -import React, { - ComponentType, - Fragment, - useContext, - useEffect, - useRef, - useState, -} from "react"; -import { useSearchParams } from "react-router-dom"; -import { ConfirmModalState } from "../../components/confirmer/ConfirmModal"; +import React, { ComponentType, useContext, useRef } from "react"; export type Submit = { submit: (endState: T) => void; @@ -22,6 +13,7 @@ export type ConfirmContextType = { component: ComponentType & P>, props: Partial

) => CancelablePromise; + component?: React.ReactNode | undefined; }; export const DialogContext = React.createContext({ @@ -94,9 +86,7 @@ export const DialogProvider = ({ children }: { children: React.ReactNode }) => { }; return ( - - {Component && Component} - + {children} ); diff --git a/src/layout/page/Refetcher.tsx b/src/layout/page/Refetcher.tsx new file mode 100644 index 0000000..0e92a05 --- /dev/null +++ b/src/layout/page/Refetcher.tsx @@ -0,0 +1,21 @@ +import { useState } from "react"; +import { BiRefresh } from "react-icons/bi"; + +export const Refetcher = (props: { refetch: () => Promise }) => { + const [refetching, setRefetching] = useState(false); + + const onClick = async () => { + setRefetching(true); + await props.refetch(); + setRefetching(false); + }; + + return ( + + ); +}; diff --git a/src/linker.tsx b/src/linker.tsx index 43a5c43..eff4a8a 100644 --- a/src/linker.tsx +++ b/src/linker.tsx @@ -1,15 +1,15 @@ import React from "react"; import { NavLink, NavLinkProps } from "react-router-dom"; +import { Identifier } from "./mates/types"; import { CommentableModels, LinkableModels } from "./mikro/api/graphql"; -import { Accept, Identifier } from "./rekuest/postman/mater/mater-context"; import { ClassNameOptions, SmartModel, SmartModelProps, } from "./rekuest/selection/SmartModel"; -export interface CreatedSmartSmartProps - extends Omit, "accepts" | "identifier"> { +export interface CreatedSmartSmartProps + extends Omit { object: string; dropClassName?: (props: ClassNameOptions) => string; dragClassName?: (props: ClassNameOptions) => string; @@ -18,18 +18,14 @@ export interface CreatedSmartSmartProps children: React.ReactNode; } -export type CreatedSmartProps = Omit< - SmartModelProps, - "accepts" | "identifier" ->; +export type CreatedSmartProps = Omit; -export const buildSmartModel = ( - identifier: Identifier, - accepts: T[] -): React.FC> => { +export const buildSmartModel = ( + identifier: Identifier +): React.FC => { return ({ children, ...props }) => { return ( - + {children} ); @@ -92,14 +88,6 @@ const linkBuilder = (model: Identifier, to: string) => (object: string) => { return `/user/${getModelBase(model)}/${to}/${object}`; }; -const buildLinks = (model: Identifier, to: string) => { - return [ - buildBaseLink(model, to), - buildModelLink(model, to), - linkBuilder(model, to), - ]; -}; - export const buildModuleLink = (module: string) => { return ({ children, ...props }: OmitedNavLinkProps) => { return ( @@ -129,404 +117,131 @@ export const GlobalLink = ({ ); }; -export const buildSmart = ( - model: Identifier, - to: string, - accepts: T[] -) => { +export const buildSmart = (model: Identifier, to: string) => { x[model] = linkBuilder(model, to); return { DetailLink: buildModelLink(model, to), ListLink: buildBaseLink(model, to), linkBuilder: linkBuilder(model, to), - Smart: buildSmartModel(model, accepts), + Smart: buildSmartModel(model), }; }; export const Representation = buildSmart( "@mikro/representation", - "representations", - [ - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/model", - "item:@mikro/model", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", - ] + "representations" +); + +export const Image = buildSmart("@mikronext/image", "images"); + +export const History = buildSmart("@mikronext/history", "history"); + +export const TransformationView = buildSmart( + "@mikronext/transformationview", + "transformationviews" ); -export const Graph = buildSmart("@mikro/graph", "graphs", [ - "list:@mikro/graph", - "item:@mikro/graph", - "list:@mikro/model", - "item:@mikro/model", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Label = buildSmart("@mikro/label", "labels", []); -export const Feature = buildSmart("@mikro/feature", "features", []); - -export const Sample = buildSmart("@mikro/sample", "samples", [ - "list:@mikro/roi", - "item:@mikro/roi", - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Roi = buildSmart("@mikro/roi", "rois", [ - "list:@mikro/roi", - "item:@mikro/roi", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Thumbnail = buildSmart("@mikro/thumbnail", "thumbnails", [ - "list:@mikro/thumbnail", - "item:@mikro/thumbnail", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Context = buildSmart("@mikro/context", "contexts", [ - "list:@mikro/link", - "item:@mikro/link", - "list:@mikro/context", - "item:@mikro/context", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Link = buildSmart("@mikro/link", "links", [ - "list:@mikro/link", - "item:@mikro/link", - "list:@mikro/context", - "item:@mikro/context", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Model = buildSmart("@mikro/model", "models", [ - "list:@mikro/model", - "item:@mikro/model", - "list:@mikro/context", - "item:@mikro/context", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Stage = buildSmart("@mikro/stage", "stages", [ - "list:@mikro/stage", - "item:@mikro/stage", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Position = buildSmart("@mikro/position", "positions", [ - "list:@mikro/position", - "item:@mikro/position", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Video = buildSmart("@mikro/video", "videos", [ - "list:@mikro/video", - "item:@mikro/video", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const DimensionMap = buildSmart("@mikro/dimensionmap", "dimensionmaps", [ - "list:@mikro/dimensionmap", - "item:@mikro/dimensionmap", - "list:@mikro/position", - "item:@mikro/position", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Channel = buildSmart("@mikro/channel", "channels", [ - "list:@mikro/channel", - "item:@mikro/channel", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Objective = buildSmart("@mikro/objective", "objectives", [ - "list:@mikro/objective", - "item:@mikro/objective", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Instrument = buildSmart("@mikro/instrument", "instruments", [ - "list:@mikro/instrument", - "item:@mikro/instrument", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const MikroFile = buildSmart("@mikro/omerofile", "files", [ - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/omerofile", - "item:@mikro/omerofile", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const View = buildSmart("@mikro/view", "views", [ - "list:@mikro/view", - "item:@mikro/view", - "list:@mikro/omerofile", - "item:@mikro/omerofile", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Era = buildSmart("@mikro/era", "eras", [ - "list:@mikro/era", - "item:@mikro/era", - "list:@mikro/omerofile", - "item:@mikro/omerofile", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Timepoint = buildSmart("@mikro/timepoint", "timepoints", [ - "list:@mikro/timepoint", - "item:@mikro/timepoint", - "list:@mikro/omerofile", - "item:@mikro/omerofile", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Metric = buildSmart("@mikro/metric", "metrics", [ - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/metric", - "item:@mikro/metric", - "list:@mikro/omerofile", - "item:@mikro/omerofile", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Table = buildSmart("@mikro/table", "tables", [ - "list:@mikro/roi", - "item:@mikro/roi", - "list:@mikro/table", - "item:@mikro/table", - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Plot = buildSmart("@mikro/plot", "plots", [ - "list:@mikro/plot", - "item:@mikro/plot", - "list:@mikro/table", - "item:@mikro/table", - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Experiment = buildSmart("@mikro/experiment", "experiments", [ - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/experiment", - "item:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); - -export const Dataset = buildSmart("@mikro/dataset", "datasets", [ - "list:@mikro/dataset", - "item:@mikro/dataset", - "list:@mikro/experiment", - "item:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); -export const Node = buildSmart("@rekuest/node", "nodes", [ - "list:@rekuest/node", - "item:@rekuest/node", - "list:@rekuest/assignation", - "item:@rekuest/assignation", -]); - -export const Protocol = buildSmart("@rekuest/protocol", "protocols", [ - "list:@rekuest/protocol", - "item:@rekuest/protocol", - "list:@rekuest/assignation", - "item:@rekuest/assignation", -]); - -export const Collection = buildSmart("@rekuest/collection", "collections", [ - "list:@rekuest/collection", - "item:@rekuest/collection", -]); -export const Reservation = buildSmart("@rekuest/reservation", "reservations", [ - "list:@rekuest/reservation", - "item:@rekuest/reservation", - "list:@rekuest/node", - "item:@rekuest/node", -]); +export const LabelView = buildSmart("@mikronext/labelview", "labelviews"); + +export const File = buildSmart("@mikronext/file", "files"); + +export const ChannelView = buildSmart("@mikronext/channelview", "channelviews"); + +export const OpticsView = buildSmart("@mikronext/opticsview", "opticsviews"); + +export const Graph = buildSmart("@mikro/graph", "graphs"); + +export const Label = buildSmart("@mikro/label", "labels"); +export const Feature = buildSmart("@mikro/feature", "features"); + +export const Sample = buildSmart("@mikro/sample", "samples"); + +export const Roi = buildSmart("@mikro/roi", "rois"); + +export const Thumbnail = buildSmart("@mikro/thumbnail", "thumbnails"); + +export const Context = buildSmart("@mikro/context", "contexts"); + +export const Link = buildSmart("@mikro/link", "links"); + +export const Model = buildSmart("@mikro/model", "models"); + +export const Stage = buildSmart("@mikro/stage", "stages"); + +export const Position = buildSmart("@mikro/position", "positions"); + +export const Video = buildSmart("@mikro/video", "videos"); + +export const DimensionMap = buildSmart("@mikro/dimensionmap", "dimensionmaps"); + +export const Channel = buildSmart("@mikro/channel", "channels"); + +export const Objective = buildSmart("@mikro/objective", "objectives"); + +export const Instrument = buildSmart("@mikro/instrument", "instruments"); + +export const MikroFile = buildSmart("@mikro/omerofile", "files"); + +export const View = buildSmart("@mikro/view", "views"); + +export const Era = buildSmart("@mikro/era", "eras"); + +export const Timepoint = buildSmart("@mikro/timepoint", "timepoints"); + +export const Metric = buildSmart("@mikro/metric", "metrics"); + +export const Table = buildSmart("@mikro/table", "tables"); + +export const Plot = buildSmart("@mikro/plot", "plots"); + +export const Experiment = buildSmart("@mikro/experiment", "experiments"); + +export const Dataset = buildSmart("@mikro/dataset", "datasets"); +export const Node = buildSmart("@rekuest/node", "nodes"); + +export const Protocol = buildSmart("@rekuest/protocol", "protocols"); + +export const Collection = buildSmart("@rekuest/collection", "collections"); +export const Reservation = buildSmart("@rekuest/reservation", "reservations"); export const MirrorRepository = buildSmart( "@rekuest/mirrorrepository", - "repositories", - ["list:@rekuest/mirrorrepository", "item:@rekuest/mirrorrepository"] + "repositories" ); export const AppRepository = buildSmart( "@rekuest/apprepository", - "repositories", - ["list:@rekuest/apprepository", "item:@rekuest/apprepository"] + "repositories" ); -export const Provision = buildSmart("@rekuest/provision", "provisions", [ - "list:@rekuest/provision", - "item:@rekuest/provision", -]); - -export const TestResult = buildSmart("@rekuest/testresult", "testresults", [ - "list:@rekuest/testresult", - "item:@rekuest/testresult", -]); - -export const TestCase = buildSmart("@rekuest/testcase", "testcases", [ - "list:@rekuest/testcase", - "item:@rekuest/testcase", -]); -export const Agent = buildSmart("@rekuest/agent", "agents", [ - "list:@rekuest/agent", - "item:@rekuest/agent", - "item:@rekuest/assignation", -]); -export const Assignation = buildSmart("@rekuest/assignation", "assignations", [ - "list:@rekuest/assignation", - "item:@rekuest/assignation", -]); -export const Template = buildSmart("@rekuest/template", "templates", [ - "list:@rekuest/template", - "item:@rekuest/template", -]); - -export const Workspace = buildSmart("@fluss/workspace", "workspaces", [ - "list:@fluss/workspace", - "item:@fluss/workspace", -]); -export const Flow = buildSmart("@fluss/flow", "flows", [ - "list:@fluss/run", - "item:@fluss/run", -]); -export const Run = buildSmart("@fluss/run", "runs", [ - "list:@fluss/run", - "item:@fluss/run", -]); -export const Snapshot = buildSmart("@fluss/snapshot", "snapshots", [ - "list:@fluss/run", - "item:@fluss/run", -]); - -export const User = buildSmart("@lok/user", "users", [ - "list:@lok/user", - "item:@lok/user", - "list:@mikro/sample", - "item:@mikro/sample", - "list:@mikro/experiment", - "item:@mikro/experiment", - "item:@mikro/experiment", - "list:@mikro/representation", - "item:@mikro/representation", -]); -export const Team = buildSmart("@lok/team", "teams", [ - "list:@lok/user", - "item:@lok/user", - "list:@lok/team", - "item:@lok/team", -]); - -export const Client = buildSmart("@lok/client", "clients", [ - "list:@lok/client", - "item:@lok/client", -]); - -export const App = buildSmart("@lok/app", "apps", [ - "list:@lok/app", - "item:@lok/app", -]); - -export const Release = buildSmart("@lok/c", "releases", [ - "list:@lok/release", - "item:@lok/release", -]); - -export const Container = buildSmart("@port/container", "containers", [ - "list:@port/container", - "item:@port/container", -]); - -export const Whale = buildSmart("@port/whale", "whales", [ - "list:@port/whale", - "item:@port/whale", -]); - -export const GithubRepo = buildSmart("@port/githubrepo", "githubrepos", [ - "list:@port/githubrepo", - "item:@port/githubrepo", -]); - -export const Deployment = buildSmart("@port/deployment", "deployments", [ - "list:@port/deployment", - "item:@port/deployment", -]); +export const Provision = buildSmart("@rekuest/provision", "provisions"); + +export const TestResult = buildSmart("@rekuest/testresult", "testresults"); + +export const TestCase = buildSmart("@rekuest/testcase", "testcases"); +export const Agent = buildSmart("@rekuest/agent", "agents"); +export const Assignation = buildSmart("@rekuest/assignation", "assignations"); +export const Template = buildSmart("@rekuest/template", "templates"); + +export const Workspace = buildSmart("@fluss/workspace", "workspaces"); +export const Flow = buildSmart("@fluss/flow", "flows"); +export const Run = buildSmart("@fluss/run", "runs"); +export const Snapshot = buildSmart("@fluss/snapshot", "snapshots"); + +export const User = buildSmart("@lok/user", "users"); +export const Team = buildSmart("@lok/team", "teams"); + +export const Client = buildSmart("@lok/client", "clients"); + +export const App = buildSmart("@lok/app", "apps"); + +export const Release = buildSmart("@lok/c", "releases"); + +export const Container = buildSmart("@port/container", "containers"); + +export const Whale = buildSmart("@port/whale", "whales"); + +export const GithubRepo = buildSmart("@port/githubrepo", "githubrepos"); + +export const Deployment = buildSmart("@port/deployment", "deployments"); export const RekuestLink = buildModuleLink("rekuest"); export const FlussLink = buildModuleLink("fluss"); @@ -538,7 +253,7 @@ export const FakeSmartModel = { DetailLink: buildModelLink("fake/fake", "fake"), ListLink: buildBaseLink("fake/fake", "fake"), linkBuilder: (object: string) => "fakelink", - Smart: (props: CreatedSmartProps) =>

{props.children}
, + Smart: (props: CreatedSmartProps) =>
{props.children}
, }; export const getDefaultSmartModel = (ident: Identifier) => { diff --git a/src/lok/context.tsx b/src/lok/LokContext.tsx similarity index 63% rename from src/lok/context.tsx rename to src/lok/LokContext.tsx index ebc9ddf..b3b967f 100644 --- a/src/lok/context.tsx +++ b/src/lok/LokContext.tsx @@ -2,29 +2,29 @@ import { ApolloClient, NormalizedCacheObject, useQuery } from "@apollo/client"; import React, { useContext } from "react"; import { ManConfig } from "./types"; -export type ManContextType = { +export type LokContextType = { client?: ApolloClient; configure: (config?: ManConfig) => void; config?: ManConfig; }; -export const ManContext = React.createContext({ +export const LokContext = React.createContext({ config: {} as ManConfig, configure: () => { throw Error("No Provider in context not configured"); }, }); -export const useMan = () => useContext(ManContext); +export const useLok = () => useContext(LokContext); -export const useManQuery = (query: any) => { - const { client } = useMan(); +export const useLokQuery = (query: any) => { + const { client } = useLok(); return useQuery(query, { client: client }); }; -export function withMan any>(func: T): T { +export function withLok any>(func: T): T { const Wrapped = (nana: any) => { - const { client } = useMan(); + const { client } = useLok(); return func({ ...nana, client: client }); }; return Wrapped as T; diff --git a/src/lok/guard.tsx b/src/lok/LokGuard.tsx similarity index 70% rename from src/lok/guard.tsx rename to src/lok/LokGuard.tsx index 4170dae..bfee575 100644 --- a/src/lok/guard.tsx +++ b/src/lok/LokGuard.tsx @@ -1,12 +1,12 @@ import React from "react"; -import { useMan } from "./context"; +import { useLok } from "./LokContext"; -export const ManGuard: React.FC<{ +export const LokGuard: React.FC<{ key?: string; fallback?: React.ReactNode; children: React.ReactNode; }> = ({ key, children, fallback }) => { - const { client } = useMan(); + const { client } = useLok(); if (client) return <>{children}; @@ -18,8 +18,8 @@ export const manGuarded = ( fallback?: React.ReactNode ) => { return (props: any) => ( - + - + ); }; diff --git a/src/lok/LokModule.tsx b/src/lok/LokModule.tsx new file mode 100644 index 0000000..38dc0d1 --- /dev/null +++ b/src/lok/LokModule.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { Route, Routes } from "react-router"; +import { ModuleLayout } from "../layout/ModuleLayout"; + +import { LokGuard } from "./LokGuard"; +import TeamHome from "./pages/TeamHome"; +import { LokApp } from "./pages/apps/LokApp"; +import { LokApps } from "./pages/apps/LokApps"; +import { LokClient } from "./pages/clients/LokClient"; +import { LokClients } from "./pages/clients/LokClients"; +import { LokRelease } from "./pages/releases/LokRelease"; +import { LokReleases } from "./pages/releases/LokReleases"; +import { ManTeam } from "./pages/teams/ManTeam"; +import { ManTeams } from "./pages/teams/ManTeams"; +import { ManUser } from "./pages/users/ManUser"; +import { ManUsers } from "./pages/users/ManUsers"; +import SidePane from "./panes/SidePane"; +interface Props {} + +export const MikroModule: React.FC = (props) => { + return ( + Loading}> + , + }, + ]} + > + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + ); +}; + +export default MikroModule; diff --git a/src/lok/LokProvider.tsx b/src/lok/LokProvider.tsx new file mode 100644 index 0000000..8141489 --- /dev/null +++ b/src/lok/LokProvider.tsx @@ -0,0 +1,41 @@ +import { ApolloClient, NormalizedCacheObject } from "@apollo/client"; +import React, { useState } from "react"; +import { LokContext } from "./LokContext"; +import { createManClient } from "./client"; +import { LokConfig } from "./types"; + +export type LokProviderProps = { + register?: boolean; + children: React.ReactNode; +}; + +export const LokProvider: React.FC = ({ + register = true, + children, +}) => { + const [client, setClient] = useState< + ApolloClient | undefined + >(); + const [config, setConfig] = useState(); + + const configure = (config?: LokConfig) => { + setConfig(config); + if (!config) { + setClient(undefined); + return; + } + + setClient(createManClient(config)); + }; + + return ( + + {children} + + ); +}; diff --git a/src/lok/components/App.tsx b/src/lok/components/App.tsx index 44306df..360a40e 100644 --- a/src/lok/components/App.tsx +++ b/src/lok/components/App.tsx @@ -6,7 +6,7 @@ import { SectionTitle } from "../../layout/SectionTitle"; import { Release } from "../../linker"; import { useMikro } from "../../mikro/MikroContext"; import { useAppQuery } from "../api/graphql"; -import { withMan } from "../man"; +import { withLok } from "../LokContext"; import { ChangeAppDialog } from "./dialogs/ChangeAppDialog"; export type AppProps = { @@ -14,7 +14,7 @@ export type AppProps = { }; export const App: React.FC = (props) => { - const { data } = withMan(useAppQuery)({ variables: { id: props.id } }); + const { data } = withLok(useAppQuery)({ variables: { id: props.id } }); const { s3resolve } = useMikro(); diff --git a/src/lok/components/AppImage.tsx b/src/lok/components/AppImage.tsx index e833039..d5a386a 100644 --- a/src/lok/components/AppImage.tsx +++ b/src/lok/components/AppImage.tsx @@ -1,12 +1,12 @@ import { useMikro } from "../../mikro/MikroContext"; import { useAppQuery } from "../api/graphql"; -import { withMan } from "../man"; +import { withLok } from "../LokContext"; export const AppImage: React.FC<{ identifier: string; className?: string; }> = ({ identifier, ...props }) => { - const { data, error } = withMan(useAppQuery)({ + const { data, error } = withLok(useAppQuery)({ variables: { identifier }, }); diff --git a/src/lok/components/AppTag.tsx b/src/lok/components/AppTag.tsx index 9b04f7d..5875a83 100644 --- a/src/lok/components/AppTag.tsx +++ b/src/lok/components/AppTag.tsx @@ -1,12 +1,12 @@ import { Release } from "../../linker"; import { useReleaseQuery } from "../api/graphql"; -import { withMan } from "../man"; +import { withLok } from "../LokContext"; export const ReleaseTag: React.FC<{ version: string; identifier: string }> = ({ version, identifier, }) => { - const { data, error } = withMan(useReleaseQuery)({ + const { data, error } = withLok(useReleaseQuery)({ variables: { identifier, version }, }); diff --git a/src/lok/components/Application.tsx b/src/lok/components/Application.tsx index eba76ca..97aff8b 100644 --- a/src/lok/components/Application.tsx +++ b/src/lok/components/Application.tsx @@ -5,7 +5,7 @@ import { } from "../../lok/api/graphql"; import { withRekuest } from "../../rekuest"; import { AgentStatus, useAgentsQuery } from "../../rekuest/api/graphql"; -import { withMan } from "../man"; +import { withLok } from "../LokContext"; export type IAppProps = { clientId: string; @@ -18,7 +18,7 @@ const isBackendApp = ( }; const Application: React.FC = ({ clientId }) => { - const { data } = withMan(useDetailClientQuery)({ + const { data } = withLok(useDetailClientQuery)({ variables: { clientId: clientId }, }); diff --git a/src/lok/components/Client.tsx b/src/lok/components/Client.tsx index 8c5c996..f4da59e 100644 --- a/src/lok/components/Client.tsx +++ b/src/lok/components/Client.tsx @@ -1,18 +1,18 @@ import { useDatalayer } from "@jhnnsrs/datalayer"; import { PageLayout } from "../../layout/PageLayout"; import { useDialog } from "../../layout/dialog/DialogProvider"; +import { withLok } from "../LokContext"; import { ApplicationAuthorizationGrantType, useDetailClientQuery, } from "../api/graphql"; -import { withMan } from "../man"; export type AppProps = { id: string; }; export const Client: React.FC = (props) => { - const { data } = withMan(useDetailClientQuery)({ + const { data } = withLok(useDetailClientQuery)({ variables: { id: props.id }, }); diff --git a/src/lok/components/LokSearch.tsx b/src/lok/components/LokSearch.tsx index a0a193b..fc52e8e 100644 --- a/src/lok/components/LokSearch.tsx +++ b/src/lok/components/LokSearch.tsx @@ -1,12 +1,11 @@ import { Transition } from "@headlessui/react"; import { Field, Form, Formik } from "formik"; -import React, { useState } from "react"; +import { useState } from "react"; import { BiSearch } from "react-icons/bi"; import { FiArrowDown } from "react-icons/fi"; import { SwitchInputField } from "../../components/forms/fields/switch_input"; import { ChangeSubmitHelper } from "../../rekuest/ui/helpers/ChangeSubmitter"; import { LokGlobalSearchQueryVariables } from "../api/graphql"; -import { withMan } from "../context"; interface LokSearchProps { onSearch: (variables: LokGlobalSearchQueryVariables) => void; diff --git a/src/lok/components/MyPrivateFakts.tsx b/src/lok/components/MyPrivateFakts.tsx index 496dedc..8d418d8 100644 --- a/src/lok/components/MyPrivateFakts.tsx +++ b/src/lok/components/MyPrivateFakts.tsx @@ -2,23 +2,23 @@ import React from "react"; import { useConfirm } from "../../components/confirmer/confirmer-context"; import { notEmpty } from "../../floating/utils"; import { Client } from "../../linker"; +import { withLok } from "../LokContext"; import { MyPrivateClientsDocument, MyPrivateClientsQuery, useDeleteClientMutation, useMyPrivateClientsQuery, } from "../api/graphql"; -import { withMan } from "../man"; export type IAppProps = { onAppClicked?: (clientID: string) => void; }; const MyClients: React.FC = ({ onAppClicked }) => { - const { data } = withMan(useMyPrivateClientsQuery)(); + const { data } = withLok(useMyPrivateClientsQuery)(); const { confirm } = useConfirm(); - const [deletePrivateFakt] = withMan(useDeleteClientMutation)({ + const [deletePrivateFakt] = withLok(useDeleteClientMutation)({ update(cache, result) { const query = cache.readQuery({ query: MyPrivateClientsDocument, diff --git a/src/lok/components/Release.tsx b/src/lok/components/Release.tsx index a56db6a..3eb06fd 100644 --- a/src/lok/components/Release.tsx +++ b/src/lok/components/Release.tsx @@ -4,15 +4,15 @@ import { PageLayout } from "../../layout/PageLayout"; import { SectionTitle } from "../../layout/SectionTitle"; import { useDialog } from "../../layout/dialog/DialogProvider"; import { Client } from "../../linker"; +import { withLok } from "../LokContext"; import { useReleaseQuery } from "../api/graphql"; -import { withMan } from "../man"; export type AppProps = { id: string; }; export const Release: React.FC = (props) => { - const { data } = withMan(useReleaseQuery)({ variables: { id: props.id } }); + const { data } = withLok(useReleaseQuery)({ variables: { id: props.id } }); const { s3resolve } = useDatalayer(); diff --git a/src/lok/components/ReleaseEmblem.tsx b/src/lok/components/ReleaseEmblem.tsx index eead013..a9d4379 100644 --- a/src/lok/components/ReleaseEmblem.tsx +++ b/src/lok/components/ReleaseEmblem.tsx @@ -1,12 +1,12 @@ import { Release } from "../../linker"; import { useReleaseQuery } from "../api/graphql"; -import { withMan } from "../man"; +import { withLok } from "../LokContext"; export const ReleaseEmblem: React.FC<{ version: string; identifier: string; }> = ({ version, identifier }) => { - const { data, error } = withMan(useReleaseQuery)({ + const { data, error } = withLok(useReleaseQuery)({ variables: { identifier, version }, }); diff --git a/src/lok/components/UserEmblem.tsx b/src/lok/components/UserEmblem.tsx index 16e1bbd..3bde396 100644 --- a/src/lok/components/UserEmblem.tsx +++ b/src/lok/components/UserEmblem.tsx @@ -1,15 +1,14 @@ -import { Link } from "react-router-dom"; +import { useDatalayer } from "@jhnnsrs/datalayer"; import { User } from "../../linker"; -import { useMikro, withMikro } from "../../mikro/MikroContext"; +import { withLok } from "../LokContext"; import { useUserQuery } from "../api/graphql"; -import { withMan } from "../man"; export const UserEmblem: React.FC<{ sub: string }> = ({ sub }) => { - const { data, error } = withMan(useUserQuery)({ + const { data, error } = withLok(useUserQuery)({ variables: { id: sub }, }); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); return (
{data?.user?.id && ( diff --git a/src/lok/components/UserTag.tsx b/src/lok/components/UserTag.tsx index 8466e88..bf9d5b6 100644 --- a/src/lok/components/UserTag.tsx +++ b/src/lok/components/UserTag.tsx @@ -1,18 +1,17 @@ -import { Link } from "react-router-dom"; +import { useDatalayer } from "@jhnnsrs/datalayer"; import { User } from "../../linker"; -import { useMikro, withMikro } from "../../mikro/MikroContext"; +import { withLok } from "../LokContext"; import { useUserQuery } from "../api/graphql"; -import { withMan } from "../man"; export const UserTag: React.FC<{ sub: string; className?: string }> = ({ sub, className, }) => { - const { data, error } = withMan(useUserQuery)({ + const { data, error } = withLok(useUserQuery)({ variables: { id: sub }, }); - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); return (
{data?.user?.id ? ( diff --git a/src/lok/components/cards/AppCard.tsx b/src/lok/components/cards/AppCard.tsx index 325ec7d..dac8df2 100644 --- a/src/lok/components/cards/AppCard.tsx +++ b/src/lok/components/cards/AppCard.tsx @@ -1,6 +1,5 @@ -import React from "react"; +import { useDatalayer } from "@jhnnsrs/datalayer"; import { App } from "../../../linker"; -import { useMikro } from "../../../mikro/MikroContext"; import { ListAppFragment } from "../../api/graphql"; interface AppCardProps { @@ -8,7 +7,7 @@ interface AppCardProps { } export const AppCard = ({ app }: AppCardProps) => { - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); return ( { - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); return ( { - const { s3resolve } = useMikro(); + const { s3resolve } = useDatalayer(); return ( & { app: DetailAppFragment } ) => { - const [updateApp] = withMan(useUpdateAppMutation)({ + const [updateApp] = withLok(useUpdateAppMutation)({ update: (cache, { data }) => { if (data?.updateApp) { cache.modify({ diff --git a/src/lok/components/dialogs/ChangeGroupDialog.tsx b/src/lok/components/dialogs/ChangeGroupDialog.tsx index 7ddb73b..fd67749 100644 --- a/src/lok/components/dialogs/ChangeGroupDialog.tsx +++ b/src/lok/components/dialogs/ChangeGroupDialog.tsx @@ -1,26 +1,21 @@ import { Form, Formik } from "formik"; -import { FileInputField } from "../../../components/forms/fields/file_input"; import { SubmitButton } from "../../../components/forms/fields/SubmitButton"; -import { SwitchInputField } from "../../../components/forms/fields/switch_input"; +import { FileInputField } from "../../../components/forms/fields/file_input"; import { TextInputField } from "../../../components/forms/fields/text_input"; import { Submit } from "../../../layout/dialog/DialogProvider"; import { TwDialog } from "../../../layout/dialog/TwDialog"; +import { withLok } from "../../LokContext"; import { DetailGroupFragment, - DetailUserFragment, UpdateGroupMutation, UpdateGroupMutationVariables, - UpdateUserMutation, - UpdateUserMutationVariables, useUpdateGroupMutation, - useUpdateUserMutation, } from "../../api/graphql"; -import { withMan } from "../../man"; export const ChangeGroupDialog = ( props: Submit & { group: DetailGroupFragment } ) => { - const [updateGroup] = withMan(useUpdateGroupMutation)({ + const [updateGroup] = withLok(useUpdateGroupMutation)({ update: (cache, { data }) => { if (data?.updateGroup) { cache.modify({ diff --git a/src/lok/components/dialogs/ChangeMeModal.tsx b/src/lok/components/dialogs/ChangeMeModal.tsx index 1402637..eb031e3 100644 --- a/src/lok/components/dialogs/ChangeMeModal.tsx +++ b/src/lok/components/dialogs/ChangeMeModal.tsx @@ -4,6 +4,7 @@ import React from "react"; import { SubmitButton } from "../../../components/forms/fields/SubmitButton"; import { TextInputField } from "../../../components/forms/fields/text_input"; import { useModal } from "../../../components/modals/modal-context"; +import { withLok } from "../../LokContext"; import { ChangeMeMutationVariables, MeUserFragment, @@ -11,10 +12,9 @@ import { ProfileQuery, useChangeMeMutation, } from "../../api/graphql"; -import { withMan } from "../../man"; const ChangeMeModal: React.FC<{ me: MeUserFragment }> = ({ me }) => { - const [changeMe] = withMan(useChangeMeMutation)({ + const [changeMe] = withLok(useChangeMeMutation)({ update(cache, result) { cache.updateQuery( { diff --git a/src/lok/components/dialogs/ChangeUserDialog.tsx b/src/lok/components/dialogs/ChangeUserDialog.tsx index 812f6c6..9e466bf 100644 --- a/src/lok/components/dialogs/ChangeUserDialog.tsx +++ b/src/lok/components/dialogs/ChangeUserDialog.tsx @@ -1,22 +1,22 @@ import { Form, Formik } from "formik"; -import { FileInputField } from "../../../components/forms/fields/file_input"; import { SubmitButton } from "../../../components/forms/fields/SubmitButton"; +import { FileInputField } from "../../../components/forms/fields/file_input"; import { SwitchInputField } from "../../../components/forms/fields/switch_input"; import { TextInputField } from "../../../components/forms/fields/text_input"; import { Submit } from "../../../layout/dialog/DialogProvider"; import { TwDialog } from "../../../layout/dialog/TwDialog"; +import { withLok } from "../../LokContext"; import { DetailUserFragment, UpdateUserMutation, UpdateUserMutationVariables, useUpdateUserMutation, } from "../../api/graphql"; -import { withMan } from "../../man"; export const ChangeUserDialog = ( props: Submit & { user: DetailUserFragment } ) => { - const [updateUser] = withMan(useUpdateUserMutation)({ + const [updateUser] = withLok(useUpdateUserMutation)({ update: (cache, { data }) => { if (data?.updateUser) { cache.modify({ diff --git a/src/lok/components/dialogs/CreateApplicationModal.tsx b/src/lok/components/dialogs/CreateApplicationModal.tsx index 36720c3..a15ef0a 100644 --- a/src/lok/components/dialogs/CreateApplicationModal.tsx +++ b/src/lok/components/dialogs/CreateApplicationModal.tsx @@ -2,9 +2,9 @@ import { Dialog } from "@headlessui/react"; import { Form, Formik } from "formik"; import React from "react"; import { Alert } from "../../../components/forms/Alert"; +import { SubmitButton } from "../../../components/forms/fields/SubmitButton"; import { CarouselInputField } from "../../../components/forms/fields/carousel_inputs"; import { ParagraphInputField } from "../../../components/forms/fields/paragraph_input"; -import { SubmitButton } from "../../../components/forms/fields/SubmitButton"; import { TextInputField } from "../../../components/forms/fields/text_input"; import { useModal } from "../../../components/modals/modal-context"; import { @@ -13,7 +13,7 @@ import { GrantType, useCreateApplicationMutation, } from "../../../lok/api/graphql"; -import { withMan } from "../../man"; +import { withLok } from "../../LokContext"; export type ICreateApplicationModalProps = { onApplicationCreated?: (app: CreateApplicationMutation) => void; @@ -33,7 +33,7 @@ export type CreateApplicationFormValues = { const CreateApplicationModal: React.FC = ({ onApplicationCreated, }) => { - const [createApplication, data] = withMan(useCreateApplicationMutation)({ + const [createApplication, data] = withLok(useCreateApplicationMutation)({ update(cache, result) { const existingApps: any = cache.readQuery({ query: ApplicationsDocument, diff --git a/src/lok/components/dialogs/CreatePublicClient.tsx b/src/lok/components/dialogs/CreatePublicClient.tsx index fee58b0..88d4072 100644 --- a/src/lok/components/dialogs/CreatePublicClient.tsx +++ b/src/lok/components/dialogs/CreatePublicClient.tsx @@ -8,6 +8,7 @@ import { SwitchInputField } from "../../../components/forms/fields/switch_input" import { TextInputField } from "../../../components/forms/fields/text_input"; import { Submit } from "../../../layout/dialog/DialogProvider"; import { TwDialog } from "../../../layout/dialog/TwDialog"; +import { withLok } from "../../LokContext"; import { CreatePublicClientMutation, CreatePublicClientMutationVariables, @@ -15,14 +16,13 @@ import { useCreatePublicClientMutation, useScopesOptionsLazyQuery, } from "../../api/graphql"; -import { withMan } from "../../man"; export const CreatePublicClientDialog = ( props: Submit ) => { - const [createPublicFakt] = withMan(useCreatePublicClientMutation)(); + const [createPublicFakt] = withLok(useCreatePublicClientMutation)(); - const [searchScopes] = withMan(useScopesOptionsLazyQuery)(); + const [searchScopes] = withLok(useScopesOptionsLazyQuery)(); return ( diff --git a/src/lok/man.tsx b/src/lok/man.tsx deleted file mode 100644 index 7564c60..0000000 --- a/src/lok/man.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { useMan } from "./context"; - -export function withMan any>(func: T): T { - const Wrapped = (nana: any) => { - const { client } = useMan(); - - return func({ ...nana, client: client }); - }; - return Wrapped as T; -} diff --git a/src/pages/lok/TeamHome.tsx b/src/lok/pages/TeamHome.tsx similarity index 100% rename from src/pages/lok/TeamHome.tsx rename to src/lok/pages/TeamHome.tsx diff --git a/src/pages/lok/apps/LokApp.tsx b/src/lok/pages/apps/LokApp.tsx similarity index 100% rename from src/pages/lok/apps/LokApp.tsx rename to src/lok/pages/apps/LokApp.tsx diff --git a/src/pages/lok/apps/LokApps.tsx b/src/lok/pages/apps/LokApps.tsx similarity index 89% rename from src/pages/lok/apps/LokApps.tsx rename to src/lok/pages/apps/LokApps.tsx index d40708d..e947351 100644 --- a/src/pages/lok/apps/LokApps.tsx +++ b/src/lok/pages/apps/LokApps.tsx @@ -4,13 +4,13 @@ import { notEmpty } from "../../../floating/utils"; import { PageLayout } from "../../../layout/PageLayout"; import { SectionTitle } from "../../../layout/SectionTitle"; import { App } from "../../../linker"; +import { withLok } from "../../../lok/LokContext"; import { useAppsQuery } from "../../../lok/api/graphql"; -import { withMan } from "../../../lok/man"; export interface ManUserProps {} export const LokApps: React.FC = (props) => { - const { data } = withMan(useAppsQuery)(); + const { data } = withLok(useAppsQuery)(); return ( diff --git a/src/pages/lok/clients/LokClient.tsx b/src/lok/pages/clients/LokClient.tsx similarity index 100% rename from src/pages/lok/clients/LokClient.tsx rename to src/lok/pages/clients/LokClient.tsx diff --git a/src/pages/lok/clients/LokClients.tsx b/src/lok/pages/clients/LokClients.tsx similarity index 89% rename from src/pages/lok/clients/LokClients.tsx rename to src/lok/pages/clients/LokClients.tsx index ca3a0d0..4f0747d 100644 --- a/src/pages/lok/clients/LokClients.tsx +++ b/src/lok/pages/clients/LokClients.tsx @@ -4,13 +4,13 @@ import { notEmpty } from "../../../floating/utils"; import { PageLayout } from "../../../layout/PageLayout"; import { SectionTitle } from "../../../layout/SectionTitle"; import { App } from "../../../linker"; +import { withLok } from "../../../lok/LokContext"; import { useMyPrivateClientsQuery } from "../../../lok/api/graphql"; -import { withMan } from "../../../lok/man"; export interface ManUserProps {} export const LokClients: React.FC = (props) => { - const { data } = withMan(useMyPrivateClientsQuery)(); + const { data } = withLok(useMyPrivateClientsQuery)(); return ( diff --git a/src/pages/lok/releases/LokRelease.tsx b/src/lok/pages/releases/LokRelease.tsx similarity index 100% rename from src/pages/lok/releases/LokRelease.tsx rename to src/lok/pages/releases/LokRelease.tsx diff --git a/src/pages/lok/releases/LokReleases.tsx b/src/lok/pages/releases/LokReleases.tsx similarity index 90% rename from src/pages/lok/releases/LokReleases.tsx rename to src/lok/pages/releases/LokReleases.tsx index 00b7dac..7a6fb48 100644 --- a/src/pages/lok/releases/LokReleases.tsx +++ b/src/lok/pages/releases/LokReleases.tsx @@ -4,13 +4,13 @@ import { notEmpty } from "../../../floating/utils"; import { PageLayout } from "../../../layout/PageLayout"; import { SectionTitle } from "../../../layout/SectionTitle"; import { App } from "../../../linker"; +import { withLok } from "../../../lok/LokContext"; import { useReleasesQuery } from "../../../lok/api/graphql"; -import { withMan } from "../../../lok/man"; export interface ManUserProps {} export const LokReleases: React.FC = (props) => { - const { data } = withMan(useReleasesQuery)(); + const { data } = withLok(useReleasesQuery)(); return ( diff --git a/src/lok/pages/teams/ManTeam.tsx b/src/lok/pages/teams/ManTeam.tsx new file mode 100644 index 0000000..1b5b19f --- /dev/null +++ b/src/lok/pages/teams/ManTeam.tsx @@ -0,0 +1,88 @@ +import { useDatalayer } from "@jhnnsrs/datalayer"; +import React from "react"; +import { useParams } from "react-router"; +import { DropZone } from "../../../components/layout/DropZone"; +import { ResponsiveContainerGrid } from "../../../components/layout/ResponsiveContainerGrid"; +import { notEmpty } from "../../../floating/utils"; +import { ActionButton } from "../../../layout/ActionButton"; +import { PageLayout } from "../../../layout/PageLayout"; +import { useDialog } from "../../../layout/dialog/DialogProvider"; +import { withLok } from "../../LokContext"; +import { useDetailGroupQuery } from "../../api/graphql"; +import { UserCard } from "../../components/cards/UserCard"; +import { ChangeGroupDialog } from "../../components/dialogs/ChangeGroupDialog"; + +export interface ManTeamProps {} + +export const ManTeam: React.FC = (props) => { + const { team } = useParams<{ team: string }>(); + + if (!team) return <>; + + const { data } = withLok(useDetailGroupQuery)({ + variables: { id: team }, + }); + + const { s3resolve } = useDatalayer(); + const { ask } = useDialog(); + return ( + + { + if (data?.group) { + await ask(ChangeGroupDialog, { group: data?.group }); + } + }} + /> + + } + > +
+
+ {data?.group?.name} +
+ { + console.log(e); + }} + /> + +
+
Members of this Group
+ + {data?.group?.userSet?.filter(notEmpty).map((u, index) => ( + + ))} + +
+ My Shared Data with this Team +
+
+
+
+ ); +}; diff --git a/src/pages/lok/teams/ManTeams.tsx b/src/lok/pages/teams/ManTeams.tsx similarity index 100% rename from src/pages/lok/teams/ManTeams.tsx rename to src/lok/pages/teams/ManTeams.tsx diff --git a/src/lok/pages/users/ManUser.tsx b/src/lok/pages/users/ManUser.tsx new file mode 100644 index 0000000..0189513 --- /dev/null +++ b/src/lok/pages/users/ManUser.tsx @@ -0,0 +1,90 @@ +import { useDatalayer } from "@jhnnsrs/datalayer"; +import React from "react"; +import { useParams } from "react-router"; +import { FittingResponsiveContainerGrid } from "../../../components/layout/ResponsiveContainerGrid"; +import { ActionButton } from "../../../layout/ActionButton"; +import { PageLayout } from "../../../layout/PageLayout"; +import { useDialog } from "../../../layout/dialog/DialogProvider"; +import { withLok } from "../../LokContext"; +import { useDetailUserQuery } from "../../api/graphql"; +import { TeamCard } from "../../components/cards/TeamCard"; +import { ChangeUserDialog } from "../../components/dialogs/ChangeUserDialog"; + +export interface ManUserProps {} + +export const ManUser: React.FC = (props) => { + const { user } = useParams<{ user: string }>(); + + if (!user) return <>; + + const { data } = withLok(useDetailUserQuery)({ + variables: { id: user }, + }); + const { s3resolve } = useDatalayer(); + + const { ask } = useDialog(); + + return ( + + { + window.open(`mailto:${data?.user?.email}`, "_blank"); + }} + /> + { + if (data?.user) { + await ask(ChangeUserDialog, { user: data?.user }); + } + }} + /> + + } + > +
+
+ {data?.user?.firstName ? ( + <> + {data?.user.firstName} {data?.user.lastName} +
{data?.user?.username}
+ + ) : ( + data?.user?.username + )} +
+
+
Member of these Groups
+ + {data?.user?.groups?.map((u, index) => ( + + ))} + +
+ My Shared Data with this User +
+
+
+
+ ); +}; diff --git a/src/pages/lok/users/ManUsers.tsx b/src/lok/pages/users/ManUsers.tsx similarity index 100% rename from src/pages/lok/users/ManUsers.tsx rename to src/lok/pages/users/ManUsers.tsx diff --git a/src/pages/lok/LokSidebar.tsx b/src/lok/panes/SidePane.tsx similarity index 81% rename from src/pages/lok/LokSidebar.tsx rename to src/lok/panes/SidePane.tsx index d9bf6a1..8ffae1a 100644 --- a/src/pages/lok/LokSidebar.tsx +++ b/src/lok/panes/SidePane.tsx @@ -1,19 +1,15 @@ import React, { useEffect } from "react"; -import { NavLink } from "react-router-dom"; import { ResponsiveContainerGrid } from "../../components/layout/ResponsiveContainerGrid"; import { notEmpty } from "../../floating/utils"; -import { Team } from "../../linker"; +import { withLok } from "../LokContext"; import { LokGlobalSearchQueryVariables, - useLokGlobalSearchLazyQuery, useLokGlobalSearchQuery, - useMyGroupsQuery, -} from "../../lok/api/graphql"; -import { AppCard } from "../../lok/components/cards/AppCard"; -import { TeamCard } from "../../lok/components/cards/TeamCard"; -import { UserCard } from "../../lok/components/cards/UserCard"; -import { LokSearch } from "../../lok/components/LokSearch"; -import { withMan } from "../../lok/man"; +} from "../api/graphql"; +import { LokSearch } from "../components/LokSearch"; +import { AppCard } from "../components/cards/AppCard"; +import { TeamCard } from "../components/cards/TeamCard"; +import { UserCard } from "../components/cards/UserCard"; export type IMyRepresentationsProps = {}; const limit = 20; @@ -22,7 +18,7 @@ const LokSidebar: React.FC = () => { const [filter, setFilter] = React.useState({ search: "", }); - const { data, refetch } = withMan(useLokGlobalSearchQuery)({ + const { data, refetch } = withLok(useLokGlobalSearchQuery)({ //pollInterval: 1000, }); @@ -88,4 +84,4 @@ const LokSidebar: React.FC = () => { ); }; -export { LokSidebar }; +export default LokSidebar; diff --git a/src/lok/provider.tsx b/src/lok/provider.tsx deleted file mode 100644 index 624e699..0000000 --- a/src/lok/provider.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { ApolloClient, gql, NormalizedCacheObject } from "@apollo/client"; -import React, { useEffect, useState } from "react"; -import { useFakts } from "@jhnnsrs/fakts"; -import { useHerre } from "herre"; -import { createManClient } from "./client"; -import { ManContext } from "./context"; -import { ManConfig } from "./types"; - -export type ManProviderProps = { - register?: boolean; - children: React.ReactNode; -}; - -export const ManProvider: React.FC = ({ - register = true, - children, -}) => { - const [client, setClient] = useState< - ApolloClient | undefined - >(); - const [config, setConfig] = useState(); - - const configure = (config?: ManConfig) => { - setConfig(config); - if (!config) { - setClient(undefined); - return; - } - - setClient(createManClient(config)); - }; - - return ( - - {children} - - ); -}; diff --git a/src/lok/screens/Group.tsx b/src/lok/screens/Group.tsx index b8ef20c..443fc17 100644 --- a/src/lok/screens/Group.tsx +++ b/src/lok/screens/Group.tsx @@ -1,19 +1,17 @@ import React from "react"; import { DropZone } from "../../components/layout/DropZone"; import { ResponsiveGrid } from "../../components/layout/ResponsiveGrid"; -import { Modal } from "../../components/modals/Modal"; import { notEmpty } from "../../floating/utils"; import { ActionButton } from "../../layout/ActionButton"; -import { useDialog } from "../../layout/dialog/DialogProvider"; import { PageLayout } from "../../layout/PageLayout"; -import { Representation, Team, User } from "../../linker"; -import { useRepresentationsForQuery } from "../../mikro/api/graphql"; +import { useDialog } from "../../layout/dialog/DialogProvider"; +import { Representation } from "../../linker"; import { useMikro, withMikro } from "../../mikro/MikroContext"; +import { useRepresentationsForQuery } from "../../mikro/api/graphql"; import { useDetailGroupQuery } from "../api/graphql"; import { UserCard } from "../components/cards/UserCard"; import { ChangeGroupDialog } from "../components/dialogs/ChangeGroupDialog"; -import { UserEmblem } from "../components/UserEmblem"; -import { withMan } from "../man"; +import { withLok } from "../LokContext"; export type GroupProps = { id: string; @@ -45,7 +43,7 @@ export const RepresentationsForGroup = ({ name }: { name: string }) => { }; const Group: React.FC = ({ id }) => { - const { data } = withMan(useDetailGroupQuery)({ + const { data } = withLok(useDetailGroupQuery)({ variables: { id: id }, }); diff --git a/src/lok/screens/User.tsx b/src/lok/screens/User.tsx index c5cb22b..56cb2f2 100644 --- a/src/lok/screens/User.tsx +++ b/src/lok/screens/User.tsx @@ -1,22 +1,14 @@ import React from "react"; -import { - SharableModels, - useUserQuery as useArkitektUserQuery, -} from "../../rekuest/api/graphql"; import { ResponsiveGrid } from "../../components/layout/ResponsiveGrid"; -import { Modal } from "../../components/modals/Modal"; import { ActionButton } from "../../layout/ActionButton"; import { PageLayout } from "../../layout/PageLayout"; -import { Team } from "../../linker"; -import { useRepresentationsForUserQuery } from "../../mikro/api/graphql"; +import { useDialog } from "../../layout/dialog/DialogProvider"; import { useMikro, withMikro } from "../../mikro/MikroContext"; +import { useRepresentationsForUserQuery } from "../../mikro/api/graphql"; +import { withLok } from "../LokContext"; import { useDetailUserQuery } from "../api/graphql"; -import { withMan } from "../man"; -import { withRekuest } from "../../rekuest"; -import { useDialog } from "../../layout/dialog/DialogProvider"; -import { ChangeUserDialog } from "../components/dialogs/ChangeUserDialog"; -import { userInfo } from "os"; import { TeamCard } from "../components/cards/TeamCard"; +import { ChangeUserDialog } from "../components/dialogs/ChangeUserDialog"; export type UserProps = { id: string; @@ -46,7 +38,7 @@ export const ManageMikro = ({ email }: { email: string }) => { }; const User: React.FC = ({ id }) => { - const { data } = withMan(useDetailUserQuery)({ + const { data } = withLok(useDetailUserQuery)({ variables: { id: id }, }); const { s3resolve } = useMikro(); diff --git a/src/lok/types.tsx b/src/lok/types.tsx index 58fa32d..88ef5ab 100644 --- a/src/lok/types.tsx +++ b/src/lok/types.tsx @@ -1,6 +1,6 @@ import { PossibleTypesMap } from "@apollo/client"; -export type ManConfig = { +export type LokConfig = { endpointUrl: string; wsEndpointUrl: string; secure: boolean; diff --git a/src/mates/agent/useBounceAgentMate.tsx b/src/mates/agent/useBounceAgentMate.tsx index 9874132..936ab9e 100644 --- a/src/mates/agent/useBounceAgentMate.tsx +++ b/src/mates/agent/useBounceAgentMate.tsx @@ -12,11 +12,11 @@ export const useBounceAgentMate = (): AgentKickeMater => { const { confirm } = useConfirm(); const [bounce] = withRekuest(useBounceAgentMutation)(); - return (agent: { id: string; __typename?: "Agent" }) => (type, isSelf) => { - if (isSelf) { + return (agent: { id: string; __typename?: "Agent" }) => async (options) => { + if (options.partnersIncludeSelf) { return [ { - action: async (self, drops) => { + action: async (event) => { await confirm({ message: "Bounce agent", subtitle: diff --git a/src/mates/agent/useKickAgentMate.tsx b/src/mates/agent/useKickAgentMate.tsx index f99405e..7bb2076 100644 --- a/src/mates/agent/useKickAgentMate.tsx +++ b/src/mates/agent/useKickAgentMate.tsx @@ -12,11 +12,11 @@ export const useKickAgentMate = (): AgentKickeMater => { const { confirm } = useConfirm(); const [kick] = withRekuest(useKickAgentMutation)(); - return (agent: { id: string; __typename?: "Agent" }) => (type, isSelf) => { - if (isSelf) { + return (agent: { id: string; __typename?: "Agent" }) => async (options) => { + if (options.partnersIncludeSelf) { return [ { - action: async (self, drops) => { + action: async (event) => { await confirm({ message: "Kick agent", subtitle: "Are you sure you want to kick this agent?", diff --git a/src/mates/assignation/useAssignationMates.tsx b/src/mates/assignation/useAssignationMates.tsx index 0e71a11..21e9a31 100644 --- a/src/mates/assignation/useAssignationMates.tsx +++ b/src/mates/assignation/useAssignationMates.tsx @@ -1,9 +1,8 @@ import { useNavigate } from "react-router"; import { Assignation, Node } from "../../linker"; import { ListAssignationFragment } from "../../rekuest/api/graphql"; -import { usePostman } from "../../rekuest/postman/graphql/postman-context"; -import { AdditionalMate } from "../../rekuest/postman/mater/mater-context"; -import { MateFinder } from "../types"; +import { usePostman } from "../../rekuest/providers/postman/postman-context"; +import { Mate, MateFinder } from "../types"; export const useAssignationMate = (): (( ass: ListAssignationFragment @@ -11,10 +10,10 @@ export const useAssignationMate = (): (( const navigate = useNavigate(); const { ack, unassign } = usePostman(); - return (ass) => (type, isSelf) => { - let mates: AdditionalMate[] = []; + return (ass) => async (options) => { + let mates: Mate[] = []; - if (!isSelf) { + if (!options.partnersIncludeSelf) { return mates; } @@ -28,14 +27,14 @@ export const useAssignationMate = (): (( mates.push({ action: async () => { - await unassign({ variables: { assignation: ass?.id } }); + await unassign({ assignation: ass?.id }); }, label: "Cancel", }); mates.push({ action: async () => { - await ack({ variables: { assignation: ass?.id } }); + await ack({ assignation: ass?.id }); }, label: "Ack", }); diff --git a/src/mates/compose.tsx b/src/mates/compose.tsx index 491f1ac..87c80f9 100644 --- a/src/mates/compose.tsx +++ b/src/mates/compose.tsx @@ -1,5 +1,4 @@ -import { AdditionalMate, Mate } from "../rekuest/postman/mater/mater-context"; -import { MateFinder } from "./types"; +import { Mate, MateFinder } from "./types"; export type SingleMateFinder = ( type: T, @@ -7,13 +6,20 @@ export type SingleMateFinder = ( ) => Mate[] | undefined; export function composeMates(mateFunctions: MateFinder[]): MateFinder { - console.log("Reducing mates", mateFunctions); - return (type: string, isSelf: boolean) => - mateFunctions.reduce((acc, f) => { - const mates = f(type, isSelf); + return async (options) => { + let allmates: Mate[] = []; + console.log("Reducing mates", mateFunctions); + + for (const f of mateFunctions) { + const mates = await f(options); + console.log("Got mates", mates); if (mates) { - acc.push(...mates); + allmates.push(...mates); } - return acc; - }, [] as AdditionalMate[]); + } + + console.log("Returning mates", allmates); + + return allmates; + }; } diff --git a/src/mates/container/useContainerLifecycleMate.tsx b/src/mates/container/useContainerLifecycleMate.tsx index b4b76e2..a6dbb36 100644 --- a/src/mates/container/useContainerLifecycleMate.tsx +++ b/src/mates/container/useContainerLifecycleMate.tsx @@ -4,14 +4,11 @@ import { withPort } from "../../port/PortContext"; import { ContainerStatus, ListContainerFragment, - usePullWhaleMutation, useRemoveContainerMutation, useRestartContainerMutation, - useScanRepoMutation, useStopContainerMutation, } from "../../port/api/graphql"; -import { AdditionalMate } from "../../rekuest/postman/mater/mater-context"; -import { MateFinder } from "../types"; +import { Mate, MateFinder } from "../types"; export const useContainerLifecycleMate = (): (( contianer: ListContainerFragment @@ -22,28 +19,25 @@ export const useContainerLifecycleMate = (): (( const [stop] = withPort(useStopContainerMutation)(); const [remove] = withPort(useRemoveContainerMutation)(); - const [scanRepo, _] = withPort(useScanRepoMutation)(); - - const [pull] = withPort(usePullWhaleMutation)(); - return (container: ListContainerFragment) => (type, isSelf) => { - let actions: AdditionalMate[] = []; - if (isSelf) { + return (container: ListContainerFragment) => async (options) => { + let actions: Mate[] = []; + if (options.partnersIncludeSelf) { actions = actions.concat([ { - action: async (self, drops) => { + action: async (event) => { await confirm({ message: "Do you really want to restart?", subtitle: "Restarting will take some seconds!", confirmLabel: "Yes restart!", }); - await restart({ variables: { id: self.object } }); + await restart({ variables: { id: event.self.id } }); }, label: "Restart", description: "Delete Run", }, { - action: async (self, drops) => { + action: async (event) => { await confirm({ message: "Do you really want to stop?", subtitle: @@ -51,7 +45,7 @@ export const useContainerLifecycleMate = (): (( confirmLabel: "Yes stop!", }); - await stop({ variables: { id: self.object } }); + await stop({ variables: { id: event.self.id } }); }, label: "Stop", description: "Delete Run", @@ -59,18 +53,22 @@ export const useContainerLifecycleMate = (): (( ]); } - if (isSelf && container.status == ContainerStatus.Exited) { + if ( + options.partnersIncludeSelf && + container.status == ContainerStatus.Exited + ) { actions = actions.concat([ { - action: async (self, drops) => { - await confirm({ - message: "Do you really want to delete?", - subtitle: - "Deletion is irreversible! You will have to deploy again!", - confirmLabel: "Yes delete!", - }); - - await remove({ variables: { id: self.object } }); + action: async (event) => { + for (const partner of event.partners) { + await confirm({ + message: "Do you really want to delete?", + subtitle: + "Deletion is irreversible! You will have to deploy again!", + confirmLabel: "Yes delete!", + }); + await remove({ variables: { id: partner.id } }); + } }, label: , description: "Delete Container", diff --git a/src/mates/dataset/useExportDatasetMate.tsx b/src/mates/dataset/useExportDatasetMate.tsx index d89a605..bc5b79f 100644 --- a/src/mates/dataset/useExportDatasetMate.tsx +++ b/src/mates/dataset/useExportDatasetMate.tsx @@ -4,16 +4,16 @@ import { MateFinder } from "../types"; export const useExportDatasetMate = (): MateFinder => { const { confirm } = useConfirm(); - return (type, isSelf) => { - if (isSelf || type == "list:@mikro/dataset") { + return async (options) => { + if (options.partnersIncludeSelf) { return [ { - action: async (self, partner, progress) => { - await progress(0.1); + action: async (event) => { + await event.progress(0.1); await confirm({ message: "Are you sure you want to export this dataset?", }); - await progress(0.5); + await event.progress(0.5); await new Promise((r) => setTimeout(r, 1000)); }, label: <>Export, diff --git a/src/mates/dataset/usePutDatasetsMate.tsx b/src/mates/dataset/usePutDatasetsMate.tsx index 2b7eb1f..05c3a23 100644 --- a/src/mates/dataset/usePutDatasetsMate.tsx +++ b/src/mates/dataset/usePutDatasetsMate.tsx @@ -1,27 +1,17 @@ -import { BsTrash } from "react-icons/bs"; import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - usePutDatasetsMutation, - useReleaseDatasetsMutation, - useReleaseFilesMutation, -} from "../../mikro/api/graphql"; import { withMikro } from "../../mikro/MikroContext"; -import { Mate } from "../../rekuest/postman/mater/mater-context"; +import { usePutDatasetsMutation } from "../../mikro/api/graphql"; import { MateFinder } from "../types"; export const usePutDatasetsMate = (datasetID: string): MateFinder => { const { confirm } = useConfirm(); const [put] = withMikro(usePutDatasetsMutation)(); - return (type, isSelf) => { - if (isSelf || type == "list:@mikro/dataset") { + return async (options) => { + if (options.partnersIncludeSelf) { return [ { - action: async (self, partner) => { + action: async (event) => { await confirm({ message: "Are you sure you want to puth these datasets in this dataset", @@ -29,7 +19,7 @@ export const usePutDatasetsMate = (datasetID: string): MateFinder => { put({ variables: { - datasets: partner.map((p) => p.object), + datasets: event.partners.map((p) => p.id), dataset: datasetID, }, }); diff --git a/src/mates/dataset/useReleaseDatasetMate.tsx b/src/mates/dataset/useReleaseDatasetMate.tsx index 112864c..9cf6cb6 100644 --- a/src/mates/dataset/useReleaseDatasetMate.tsx +++ b/src/mates/dataset/useReleaseDatasetMate.tsx @@ -1,26 +1,17 @@ -import { BsTrash } from "react-icons/bs"; import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - useReleaseDatasetsMutation, - useReleaseFilesMutation, -} from "../../mikro/api/graphql"; import { withMikro } from "../../mikro/MikroContext"; -import { Mate } from "../../rekuest/postman/mater/mater-context"; +import { useReleaseDatasetsMutation } from "../../mikro/api/graphql"; import { MateFinder } from "../types"; export const useReleaseDatasetMate = (datasetID: string): MateFinder => { const { confirm } = useConfirm(); const [release] = withMikro(useReleaseDatasetsMutation)(); - return (type, isSelf) => { - if (isSelf || type == "list:@mikro/dataset") { + return async (options) => { + if (options.partners == "list:@mikro/dataset") { return [ { - action: async (self, partner) => { + action: async (event) => { await confirm({ message: "Are you sure you want to release this datasets from this dataset", @@ -28,7 +19,7 @@ export const useReleaseDatasetMate = (datasetID: string): MateFinder => { release({ variables: { - datasets: partner.map((p) => p.object), + datasets: event.partners.map((p) => p.id), dataset: datasetID, }, }); diff --git a/src/mates/file/useDownloadFileMate.tsx b/src/mates/file/useDownloadFileMate.tsx index 56e25f3..98176de 100644 --- a/src/mates/file/useDownloadFileMate.tsx +++ b/src/mates/file/useDownloadFileMate.tsx @@ -7,11 +7,11 @@ export const useDownloadFileMate = (): (( ) => MateFinder) => { const { s3resolve } = useDatalayer(); - return (filepath: string | undefined) => (type, isSelf) => - isSelf + return (filepath: string | undefined) => async (options) => + options.partnersIncludeSelf ? [ { - action: async (self, partner) => { + action: async (event) => { filepath && window.open(s3resolve(filepath)); }, label: , diff --git a/src/mates/file/useReleaseFileMate.tsx b/src/mates/file/useReleaseFileMate.tsx index 24c5333..3e8808b 100644 --- a/src/mates/file/useReleaseFileMate.tsx +++ b/src/mates/file/useReleaseFileMate.tsx @@ -1,33 +1,28 @@ -import { BsTrash } from "react-icons/bs"; import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - useReleaseFilesMutation, -} from "../../mikro/api/graphql"; import { withMikro } from "../../mikro/MikroContext"; -import { Mate } from "../../rekuest/postman/mater/mater-context"; +import { useReleaseFilesMutation } from "../../mikro/api/graphql"; import { MateFinder } from "../types"; export const useReleaseFileMate = (datasetID: string): MateFinder => { const { confirm } = useConfirm(); const [releaseFiles] = withMikro(useReleaseFilesMutation)(); - return (type, isSelf) => { - if (isSelf || type == "list:@mikro/omerofile") { + return async (options) => { + if ( + options.partnersIncludeSelf || + options.partners == "list:@mikro/omerofile" + ) { return [ { - action: async (self, partner) => { + action: async (event) => { await confirm({ message: - "Are you sure you want to release this file from this dataset", + "Are you sure you want to release these file from this dataset", }); releaseFiles({ variables: { - files: partner.map((p) => p.object), + files: event.partners.map((p) => p.id), dataset: datasetID, }, }); diff --git a/src/mates/generics/buildDeleteMate.tsx b/src/mates/generics/buildDeleteMate.tsx index ac75feb..fd19802 100644 --- a/src/mates/generics/buildDeleteMate.tsx +++ b/src/mates/generics/buildDeleteMate.tsx @@ -19,46 +19,18 @@ export function buildDeleteMate( const [deleteItem] = xfunction({} as any); - return (object: DeletableObject) => (type, isSelf) => { - if (isSelf) { + return (object: DeletableObject) => async (options) => { + if (options.partnersIncludeSelf) { return [ { - action: async (self, partner) => { - await confirm({ - message: `Are you sure you want to delete this ${object.__typename}?`, - }); - - deleteItem({ - variables: { id: partner[0].object }, - update(cache: any, result: any, options: any) { - if (object.__typename) { - const normalizedId = cache.identify(object); - cache.evict({ id: normalizedId }); - cache.gc(); - } - }, - }); - }, - label: ( - <> - - - ), - description: `Delete this ${object.__typename}`, - }, - ]; - } - if (type == "list:@mikro/omerofile") { - return [ - { - action: async (self, partners) => { - await confirm({ - message: "Are you sure you want to delete all these contexts?", - }); + action: async (event) => { + for (const partner of event.partners) { + await confirm({ + message: `Are you sure you want to delete this ${object.__typename}?`, + }); - for (let partner of partners) { - await deleteItem({ - variables: { id: partner.object }, + deleteItem({ + variables: { id: partner.id }, update(cache: any, result: any, options: any) { if (object.__typename) { const normalizedId = cache.identify(object); @@ -71,10 +43,10 @@ export function buildDeleteMate( }, label: ( <> - Delete All + ), - description: "Delete all contexts", + description: `Delete this ${object.__typename}`, }, ]; } diff --git a/src/mates/generics/buildPinMate.tsx b/src/mates/generics/buildPinMate.tsx index 942d6b4..f2a5ce7 100644 --- a/src/mates/generics/buildPinMate.tsx +++ b/src/mates/generics/buildPinMate.tsx @@ -17,17 +17,19 @@ export function buildPinMate(xfunction: PinFunction): () => DeleteObjectFinder { const [pinFunction] = xfunction({} as any); - return (object: PinnableObject) => (type, isSelf) => { - if (isSelf) { + return (object: PinnableObject) => async (options) => { + if (options.partnersIncludeSelf) { return [ { - action: async (self, partner) => { - pinFunction({ - variables: { - id: partner[0].object, - pin: object.pinned == undefined ? true : !object.pinned, - }, - }); + action: async (event) => { + for (const partner of event.partners) { + pinFunction({ + variables: { + id: partner.id, + pin: object.pinned == undefined ? true : !object.pinned, + }, + }); + } }, label: <>{object.pinned != false ? : }, description: `Pin this ${object.__typename}`, diff --git a/src/mates/generics/useLinkMate.tsx b/src/mates/generics/useLinkMate.tsx index 05774fe..bc8f49d 100644 --- a/src/mates/generics/useLinkMate.tsx +++ b/src/mates/generics/useLinkMate.tsx @@ -11,42 +11,46 @@ export const useMikroLinkMate = (): MateFinder => { const { alert } = useAlert(); const [link] = withMikro(useLinkMutation)({}); - return (type: string, isSelf: boolean) => - isSelf + return async (options) => { + return options.partnersIncludeSelf ? undefined : [ { - action: async (self, drops) => { - let leftType = identifierToLinkableModel(self.identifier); - let rightType = identifierToLinkableModel(drops[0].identifier); + action: async (event) => { + for (const partner of event.partners) { + let leftType = identifierToLinkableModel(event.self.identifier); + let rightType = identifierToLinkableModel(partner.identifier); - if (!leftType || !rightType) { - await alert({ - message: "Cannot relate these two objects", - confirmLabel: "Ok, the developer should really fix this", - }); - return; - } + if (!leftType || !rightType) { + await alert({ + message: "Cannot relate these two objects", + confirmLabel: "Ok, the developer should really fix this", + }); + return; + } - let x = await ask(AskRelationModal, { - leftIdentifier: self.identifier, - leftObject: self.object, - rightIdentifier: drops[0].identifier, - rightObject: drops[0].object, - }); + console.log(leftType, rightType); + let x = await ask(AskRelationModal, { + leftIdentifier: event.self.identifier, + leftObject: event.self.id, + rightIdentifier: partner.identifier, + rightObject: partner.id, + }); - await link({ - variables: { - leftType: leftType, - rightType: rightType, - leftId: self.object, - rightId: drops[0].object, - ...x, - }, - }); + await link({ + variables: { + leftType: leftType, + rightType: rightType, + leftId: event.self.id, + rightId: partner.id, + ...x, + }, + }); + } }, label: "Relate", description: "Relate to other", }, ]; + }; }; diff --git a/src/mates/nodes/useNodeActionMate.tsx b/src/mates/nodes/useNodeActionMate.tsx index 22253c2..2c321a0 100644 --- a/src/mates/nodes/useNodeActionMate.tsx +++ b/src/mates/nodes/useNodeActionMate.tsx @@ -3,41 +3,34 @@ import { useDialog } from "../../layout/dialog/DialogProvider"; import { Flow } from "../../linker"; import { NodeListItemFragment } from "../../rekuest/api/graphql"; import { ReserveDialog } from "../../rekuest/components/dialogs/ReserveDialog"; -import { AdditionalMate } from "../../rekuest/postman/mater/mater-context"; -import { useRequester } from "../../rekuest/postman/requester/requester-context"; -import { useReserver } from "../../rekuest/postman/reserver/reserver-context"; -import { MateFinder } from "../types"; +import { usePostman } from "../../rekuest/providers/postman/postman-context"; +import { useSettings } from "../../settings/settings-context"; +import { Mate, MateFinder } from "../types"; export const useNodeActionMate = (): (( node: NodeListItemFragment ) => MateFinder) => { - const { assign, unassign } = useRequester(); - const { ask } = useDialog(); - const { reserve } = useReserver(); + const { reserve } = usePostman(); + const { settings } = useSettings(); const navigate = useNavigate(); - return (node) => (type, isSelf) => { - let mates: AdditionalMate[] = []; - if (!isSelf) { + return (node) => async (options) => { + let mates: Mate[] = []; + if (!options.partnersIncludeSelf) { return mates; } mates.push({ action: async () => { - await reserve({ node: node.id }); + let res = await ask(ReserveDialog, { + initial: { node: node.id, instanceId: settings.instanceId }, + }); + await reserve(res); }, label: "Reserve", }); - mates.push({ - action: async () => { - let res = await ask(ReserveDialog, { initial: { node: node.id } }); - console.log(res); - }, - label: "Reserve New", - }); - if (node.interfaces?.includes("workflow") && node.meta?.flow) { mates.push({ action: async () => { diff --git a/src/mates/postman/usePostmanMates.tsx b/src/mates/postman/usePostmanMates.tsx new file mode 100644 index 0000000..de1d606 --- /dev/null +++ b/src/mates/postman/usePostmanMates.tsx @@ -0,0 +1,59 @@ +import { withRekuest } from "../../rekuest"; +import { + PortKindInput, + useThisFilteredReservationsLazyQuery, +} from "../../rekuest/api/graphql"; +import { useRequester } from "../../rekuest/providers/requester/requester-context"; +import { useSettings } from "../../settings/settings-context"; +import { MateFinder } from "../types"; + +export const usePostmanMate: () => MateFinder = () => { + const { assign } = useRequester(); + const { settings } = useSettings(); + + const [find] = withRekuest(useThisFilteredReservationsLazyQuery)(); + + return async (options) => { + if (options.justSelf) { + try { + let reservations = await find({ + fetchPolicy: "network-only", + variables: { + instanceId: settings.instanceId, + inputPortDemands: [ + { + at: 0, + kind: PortKindInput.Structure, + identifier: options.self.identifier, + }, + ], + }, + }); + + console.log("reservations", reservations); + + if (reservations.data?.reservations) { + return reservations.data.reservations.map((r) => ({ + action: async (event) => { + let key = r?.node?.args?.at(0)?.key; + console.log(key); + + await assign({ + reservation: r, + defaults: key ? { [key]: event.self.id } : {}, + }); + return "Assigned"; + }, + label: r?.title || r?.node.name, + })); + } + } catch (e) { + console.error(e); + } + + return []; + } + + return []; + }; +}; diff --git a/src/mates/provision/useLinkProvisionMate.tsx b/src/mates/provision/useLinkProvisionMate.tsx index 6e9b994..34546e3 100644 --- a/src/mates/provision/useLinkProvisionMate.tsx +++ b/src/mates/provision/useLinkProvisionMate.tsx @@ -7,14 +7,14 @@ export const useLinkProvisionMate = (res: { id: string }): MateFinder => { const { confirm } = useConfirm(); const [link] = withRekuest(useLinkMutation)(); - return (type, isSelf) => { - if (isSelf) { + return async (options) => { + if (options.justSelf) { return [ { - action: async (self, drops) => { + action: async (event) => { await link({ variables: { - provision: self?.object, + provision: event.self.id, reservation: res.id, }, }); diff --git a/src/mates/provision/useUnlinkProvisionMate.tsx b/src/mates/provision/useUnlinkProvisionMate.tsx index 70aac03..dce922e 100644 --- a/src/mates/provision/useUnlinkProvisionMate.tsx +++ b/src/mates/provision/useUnlinkProvisionMate.tsx @@ -7,14 +7,14 @@ export const useUnlinkProvisionMate = (res: { id: string }): MateFinder => { const { confirm } = useConfirm(); const [unlink] = withRekuest(useUnlinkMutation)(); - return (type, isSelf) => { - if (isSelf) { + return async (options) => { + if (options.justSelf) { return [ { - action: async (self, drops) => { + action: async (event) => { await unlink({ variables: { - provision: self?.object, + provision: event.self.id, reservation: res.id, }, }); diff --git a/src/mates/repo/useGithubRepoLifecycleMate.tsx b/src/mates/repo/useGithubRepoLifecycleMate.tsx index f935f32..58cee60 100644 --- a/src/mates/repo/useGithubRepoLifecycleMate.tsx +++ b/src/mates/repo/useGithubRepoLifecycleMate.tsx @@ -1,38 +1,21 @@ -import { update } from "@react-spring/web"; -import { BsTrash } from "react-icons/bs"; -import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - useReleaseFilesMutation, -} from "../../mikro/api/graphql"; -import { withMikro } from "../../mikro/MikroContext"; +import { withPort } from "../../port/PortContext"; import { DeploymentsDocument, - usePullWhaleMutation, - useRunWhaleMutation, useScanRepoMutation, } from "../../port/api/graphql"; -import { withPort } from "../../port/PortContext"; -import { Mate } from "../../rekuest/postman/mater/mater-context"; import { MateFinder } from "../types"; export const useGithubRepoLifecycleMate = (): MateFinder => { - const { confirm } = useConfirm(); - const [scanRepo, _] = withPort(useScanRepoMutation)({ refetchQueries: [DeploymentsDocument], }); - const [pull] = withPort(usePullWhaleMutation)(); - return (type, isSelf) => { - if (type == "item:@port/githubrepo") { + return async (options) => { + if (options.justSelf) { return [ { - action: async (self, drops) => { - await scanRepo({ variables: { id: self.object } }); + action: async (event) => { + await scanRepo({ variables: { id: event.self.id } }); }, label: "Scan", description: "Scan Repo", diff --git a/src/mates/representation/useReleaseRepresentationMate.tsx b/src/mates/representation/useReleaseRepresentationMate.tsx index 9640444..20bff2c 100644 --- a/src/mates/representation/useReleaseRepresentationMate.tsx +++ b/src/mates/representation/useReleaseRepresentationMate.tsx @@ -1,35 +1,30 @@ -import { BsTrash } from "react-icons/bs"; import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - useReleaseFilesMutation, - useReleaseRepresentationsMutation, - useReleaseSamplesMutation, -} from "../../mikro/api/graphql"; import { withMikro } from "../../mikro/MikroContext"; -import { Mate } from "../../rekuest/postman/mater/mater-context"; +import { useReleaseRepresentationsMutation } from "../../mikro/api/graphql"; import { MateFinder } from "../types"; export const useReleaseRepresentationMate = (datasetID: string): MateFinder => { const { confirm } = useConfirm(); - const [releaseFiles] = withMikro(useReleaseRepresentationsMutation)(); + const [releaseRepresentations] = withMikro( + useReleaseRepresentationsMutation + )(); - return (type, isSelf) => { - if (isSelf || type == "list:@mikro/representation") { + return async (options) => { + if ( + options.partners == "list:@mikro/representation" || + options.partners == "item:@mikro/representation" + ) { return [ { - action: async (self, partner) => { + action: async (event) => { await confirm({ message: - "Are you sure you want to release this file from this dataset", + "Are you sure you want to release these images from this dataset", }); - releaseFiles({ + releaseRepresentations({ variables: { - representations: partner.map((p) => p.object), + representations: event.partners.map((p) => p.id), dataset: datasetID, }, }); diff --git a/src/mates/reservation/useRequesterMate.tsx b/src/mates/reservation/useRequesterMate.tsx index 6899e48..4c666bb 100644 --- a/src/mates/reservation/useRequesterMate.tsx +++ b/src/mates/reservation/useRequesterMate.tsx @@ -1,24 +1,10 @@ -import { BsTrash } from "react-icons/bs"; -import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - useReleaseFilesMutation, -} from "../../mikro/api/graphql"; -import { withMikro } from "../../mikro/MikroContext"; import { ListReservationFragment, ReservationStatus, } from "../../rekuest/api/graphql"; -import { usePostman } from "../../rekuest/postman/graphql/postman-context"; -import { - AdditionalMate, - Mate, -} from "../../rekuest/postman/mater/mater-context"; -import { useRequester } from "../../rekuest/postman/requester/requester-context"; -import { MateFinder } from "../types"; +import { usePostman } from "../../rekuest/providers/postman/postman-context"; +import { useRequester } from "../../rekuest/providers/requester/requester-context"; +import { Mate, MateFinder } from "../types"; export const useRequesterMate = (): (( res: ListReservationFragment @@ -26,8 +12,8 @@ export const useRequesterMate = (): (( const { assign, unassign } = useRequester(); const { unreserve } = usePostman(); - return (res) => (type, isSelf) => { - let mates: AdditionalMate[] = []; + return (res) => async (options) => { + let mates: Mate[] = []; if (res.status === ReservationStatus.Active) { mates.push({ @@ -41,7 +27,7 @@ export const useRequesterMate = (): (( return mates.concat([ { action: async () => { - await unreserve({ variables: { reservation: res.id } }); + await unreserve({ reservation: res.id }); }, label: "Unreserve", }, diff --git a/src/mates/reservation/useReserveMate.tsx b/src/mates/reservation/useReserveMate.tsx index 6899e48..4c666bb 100644 --- a/src/mates/reservation/useReserveMate.tsx +++ b/src/mates/reservation/useReserveMate.tsx @@ -1,24 +1,10 @@ -import { BsTrash } from "react-icons/bs"; -import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - useReleaseFilesMutation, -} from "../../mikro/api/graphql"; -import { withMikro } from "../../mikro/MikroContext"; import { ListReservationFragment, ReservationStatus, } from "../../rekuest/api/graphql"; -import { usePostman } from "../../rekuest/postman/graphql/postman-context"; -import { - AdditionalMate, - Mate, -} from "../../rekuest/postman/mater/mater-context"; -import { useRequester } from "../../rekuest/postman/requester/requester-context"; -import { MateFinder } from "../types"; +import { usePostman } from "../../rekuest/providers/postman/postman-context"; +import { useRequester } from "../../rekuest/providers/requester/requester-context"; +import { Mate, MateFinder } from "../types"; export const useRequesterMate = (): (( res: ListReservationFragment @@ -26,8 +12,8 @@ export const useRequesterMate = (): (( const { assign, unassign } = useRequester(); const { unreserve } = usePostman(); - return (res) => (type, isSelf) => { - let mates: AdditionalMate[] = []; + return (res) => async (options) => { + let mates: Mate[] = []; if (res.status === ReservationStatus.Active) { mates.push({ @@ -41,7 +27,7 @@ export const useRequesterMate = (): (( return mates.concat([ { action: async () => { - await unreserve({ variables: { reservation: res.id } }); + await unreserve({ reservation: res.id }); }, label: "Unreserve", }, diff --git a/src/mates/sample/useReleaseSampleMate.tsx b/src/mates/sample/useReleaseSampleMate.tsx index 368ceca..cdc179d 100644 --- a/src/mates/sample/useReleaseSampleMate.tsx +++ b/src/mates/sample/useReleaseSampleMate.tsx @@ -1,34 +1,28 @@ -import { BsTrash } from "react-icons/bs"; import { useConfirm } from "../../components/confirmer/confirmer-context"; -import { - MyOmeroFilesDocument, - MyOmeroFilesQuery, - MyOmeroFilesQueryVariables, - useDeleteOmeroFileMutation, - useReleaseFilesMutation, - useReleaseSamplesMutation, -} from "../../mikro/api/graphql"; import { withMikro } from "../../mikro/MikroContext"; -import { Mate } from "../../rekuest/postman/mater/mater-context"; +import { useReleaseSamplesMutation } from "../../mikro/api/graphql"; import { MateFinder } from "../types"; export const useReleaseSampleMate = (datasetID: string): MateFinder => { const { confirm } = useConfirm(); const [releaseFiles] = withMikro(useReleaseSamplesMutation)(); - return (type, isSelf) => { - if (isSelf || type == "list:@mikro/sample") { + return async (options) => { + if ( + options.partners == "list:@mikro/sample" || + options.partners == "item:@mikro/sample" + ) { return [ { - action: async (self, partner) => { + action: async (event) => { await confirm({ message: - "Are you sure you want to release this file from this dataset", + "Are you sure you want to release these samples from this dataset", }); releaseFiles({ variables: { - samples: partner.map((p) => p.object), + samples: event.partners.map((p) => p.id), dataset: datasetID, }, }); diff --git a/src/mates/scan/useDeployScanMate.tsx b/src/mates/scan/useDeployScanMate.tsx index 3ca41f4..7fa5b03 100644 --- a/src/mates/scan/useDeployScanMate.tsx +++ b/src/mates/scan/useDeployScanMate.tsx @@ -5,12 +5,12 @@ import { MateFinder } from "../types"; export const useDeployScanMate = (): MateFinder => { const { ask } = useDialog(); - return (type, isSelf) => { - if (isSelf) { + return async (options) => { + if (options.justSelf) { return [ { - action: async (self, drops) => { - let d = await ask(DeployDialog, { scan: self.object }); + action: async (event) => { + let d = await ask(DeployDialog, { scan: event.self.id }); }, label: "Appify", description: "Apiffy this scan", diff --git a/src/mates/template/useLinkProvisionMate.tsx b/src/mates/template/useLinkProvisionMate.tsx index b2a8480..2b1917c 100644 --- a/src/mates/template/useLinkProvisionMate.tsx +++ b/src/mates/template/useLinkProvisionMate.tsx @@ -8,14 +8,14 @@ export const useProvideMate = () => { const [link] = withRekuest(useProvideMutation)(); return (res: { id: string }): MateFinder => - (type, isSelf) => { - if (isSelf) { + async (options) => { + if (options.justSelf) { return [ { - action: async (self, drops) => { + action: async (event) => { await link({ variables: { - template: self?.object, + template: event.self.id, }, }); }, diff --git a/src/mates/template/useTemplateActionsMate.tsx b/src/mates/template/useTemplateActionsMate.tsx new file mode 100644 index 0000000..16b631b --- /dev/null +++ b/src/mates/template/useTemplateActionsMate.tsx @@ -0,0 +1,49 @@ +import { useNavigate } from "react-router"; +import { keyInObject } from "../../floating/utils"; +import { useDialog } from "../../layout/dialog/DialogProvider"; +import { Flow } from "../../linker"; +import { ReserveDialog } from "../../rekuest/components/dialogs/ReserveDialog"; +import { useReserver } from "../../rekuest/providers/reserver/reserver-context"; +import { Mate, MateFinder } from "../types"; + +export const useTemplateActionMate = (): ((template: { + id: string; + params?: { [key: string]: any }; +}) => MateFinder) => { + const { ask } = useDialog(); + const { reserve } = useReserver(); + const navigate = useNavigate(); + + return (template) => async (options) => { + let mates: Mate[] = []; + if (!options.justSelf) { + return mates; + } + + mates.push({ + action: async () => { + await reserve({ template: template.id }); + }, + label: "Reserve", + }); + + mates.push({ + action: async () => { + let res = await ask(ReserveDialog, { initial: { node: template.id } }); + console.log(res); + }, + label: "Reserve New", + }); + + if (keyInObject("params", template)) { + mates.push({ + action: async () => { + await navigate(Flow.linkBuilder(template.params?.flow)); + }, + label: "Show Flow", + }); + } + + return mates; + }; +}; diff --git a/src/mates/types.tsx b/src/mates/types.tsx index ae927c1..edaec9d 100644 --- a/src/mates/types.tsx +++ b/src/mates/types.tsx @@ -1,6 +1,34 @@ -import { AdditionalMate } from "../rekuest/postman/mater/mater-context"; +export type Identifier = string; -export type MateFinder = ( - type: string, - isSelf: boolean -) => AdditionalMate[] | undefined; +export type Modifier = "list" | "item"; + +export type Accept = `${Modifier}:${Identifier}`; + +export type Drop = { + identifier: Identifier; + id: string; +}; + +export type ActionEvent = { + self: Drop; + partners: Drop[]; + progress: (x: number) => Promise; +}; + +export type MateOptions = { + partners?: Drop[]; + self: Drop; + partnersIncludeSelf: boolean; + justSelf: boolean; +}; + +export type Mate = { + action: (event: ActionEvent) => Promise; + label: React.ReactNode; + className?: (options: { isOver: boolean }) => string | string; + description?: + | ((options: { self: Drop; drops: Drop[] }) => React.ReactNode) + | React.ReactNode; +}; + +export type MateFinder = (options: MateOptions) => Promise; diff --git a/src/mates/whale/useWhaleLifecycleMate.tsx b/src/mates/whale/useWhaleLifecycleMate.tsx index dd74c4f..e13faa1 100644 --- a/src/mates/whale/useWhaleLifecycleMate.tsx +++ b/src/mates/whale/useWhaleLifecycleMate.tsx @@ -20,12 +20,12 @@ export const useWhaleLifecycleMate = (): MateFinder => { refetchQueries: ["ListWhales"], }); - return (type, isSelf) => { - if (type == "item:@port/whale") { + return async (options) => { + if (options.justSelf) { return [ { - action: async (self, drops) => { - let x = await ask(RunWhaleDialog, { whale: self.object }); + action: async (event) => { + let x = await ask(RunWhaleDialog, { whale: event.self.id }); await deploy({ variables: x }); }, @@ -33,26 +33,26 @@ export const useWhaleLifecycleMate = (): MateFinder => { description: "Deploy Whale", }, { - action: async (self, drops) => { + action: async (event) => { await confirm({ message: "Do you really want to update this whale?", confirmLabel: "Yes deploy!", }); - await pull({ variables: { id: self.object } }); + await pull({ variables: { id: event.self.id } }); }, label: "Pull", description: "Pull Update", }, { - action: async (self, drops) => { + action: async (event) => { await confirm({ message: "Do you really want to delete the downloaded image for this whale (you need to pull before deploying it!)?", confirmLabel: "Yes deploy!", }); - await purge({ variables: { id: self.object } }); + await purge({ variables: { id: event.self.id } }); }, label: "Purge", description: "Purge Image", diff --git a/src/mikro/MikroContext.tsx b/src/mikro/MikroContext.tsx index 669fa09..daff498 100644 --- a/src/mikro/MikroContext.tsx +++ b/src/mikro/MikroContext.tsx @@ -1,18 +1,14 @@ -import { MikroClient, MikroConfig } from "./types"; -import React, { useContext } from "react"; import { useQuery } from "@apollo/client"; +import React, { useContext } from "react"; +import { MikroClient, MikroConfig } from "./types"; export type MikroContextType = { client?: MikroClient; - configure: (config: MikroConfig) => void; - s3resolve: (path?: string | null) => string; + configure: (config: MikroConfig | undefined) => void; config?: MikroConfig; }; export const MikroContext = React.createContext({ - s3resolve: () => { - throw Error("No Provider in context not configured"); - }, configure: () => { throw Error("No Provider in context not configured"); }, @@ -28,6 +24,8 @@ export const useMikroQuery = (query: any) => { export function withMikro any>(func: T): T { const Wrapped = (nana: any) => { const { client } = useMikro(); + if (!client) throw Error("No MikroClient in context"); + return func({ ...nana, client: client }); }; return Wrapped as T; diff --git a/src/mikro/MikroModule.tsx b/src/mikro/MikroModule.tsx new file mode 100644 index 0000000..7a77fdc --- /dev/null +++ b/src/mikro/MikroModule.tsx @@ -0,0 +1,153 @@ +import React from "react"; +import { Route, Routes } from "react-router"; +import { Live } from "../dashboard/Dashboard"; +import { ModuleLayout } from "../layout/ModuleLayout"; +import { MikroGuard } from "./MikroGuard"; +import { DataChannel } from "./pages/channels/DataChannel"; +import { DataDataset } from "./pages/datasets/DataDataset"; +import { DataDatasets } from "./pages/datasets/DataDatasets"; +import { DataEra } from "./pages/eras/DataEra"; +import { DataEras } from "./pages/eras/DataEras"; +import { DataFile } from "./pages/files/DataFile"; +import { DataFiles } from "./pages/files/DataFiles"; +import DataGraph from "./pages/graphs/DataGraph"; +import DataGraphs from "./pages/graphs/DataGraphs"; +import { DataInstrument } from "./pages/instruments/DataInstrument"; +import { DataInstruments } from "./pages/instruments/DataInstruments"; +import { DataLabel } from "./pages/labels/DataLabel"; +import { DataLabels } from "./pages/labels/DataLabels"; +import { DataLive } from "./pages/live/DataLive"; +import { DataLives } from "./pages/live/DataLives"; +import { DataMeta } from "./pages/metas/DataMeta"; +import { DataMetas } from "./pages/metas/DataMetas"; +import { DataMetric } from "./pages/metrics/DataMetric"; +import { DataMetrics } from "./pages/metrics/DataMetrics"; +import { DataObjective } from "./pages/objectives/DataObjective"; +import { DataObjectives } from "./pages/objectives/DataObjectives"; +import { DataPlot } from "./pages/plots/DataPlot"; +import { DataPlots } from "./pages/plots/DataPlots"; +import { DataPosition } from "./pages/positions/DataPosition"; +import { DataPositions } from "./pages/positions/DataPositions"; +import { DataProvenance } from "./pages/provenance/DataProvenance"; +import { DataRepresentation } from "./pages/representations/DataRepresentation"; +import { DataRepresentations } from "./pages/representations/DataRepresentations"; +import { DataRoi } from "./pages/rois/DataRoi"; +import { DataSample } from "./pages/samples/DataSample"; +import { DataSamples } from "./pages/samples/DataSamples"; +import { DataStage } from "./pages/stages/DataStage"; +import { DataStages } from "./pages/stages/DataStages"; +import { DataTable } from "./pages/tables/DataTable"; +import { DataTables } from "./pages/tables/DataTables"; +import DataThumbnail from "./pages/thumbnails/DataThumbnail"; +import DataThumbnails from "./pages/thumbnails/DataThumbnails"; +import { DataTimepoint } from "./pages/timepoints/DataTimepoint"; +import { DataTimepoints } from "./pages/timepoints/DataTimepoints"; +import DataVideo from "./pages/videos/DataVideo"; +import DataVideos from "./pages/videos/DataVideos"; +import DataSidePanel from "./sidepanels/DataSidePanel"; +export const DataHome = React.lazy(() => import("./pages/Home")); +export const DataExperiments = React.lazy( + () => import("./pages/experiments/DataExperiments") +); +export const DataExperiment = React.lazy( + () => import("./pages/experiments/DataExperiment") +); +export const DataModels = React.lazy(() => import("./pages/models/DataModels")); +export const DataModel = React.lazy(() => import("./pages/models/DataModel")); +export const DataContexts = React.lazy( + () => import("./pages/contexts/DataContexts") +); +export const DataContext = React.lazy( + () => import("./pages/contexts/DataContext") +); + +export const DataLink = React.lazy(() => import("./pages/links/DataLink")); +export const DataLinks = React.lazy(() => import("./pages/links/DataLinks")); + +interface Props {} + +export const MikroModule: React.FC = (props) => { + return ( + Loading}> + , + }, + ]} + > + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + } /> + } /> + + } /> + } /> + + } /> + } /> + + } /> + } /> + + } /> + } /> + + } /> + } /> + + } /> + } /> + } + /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + } /> + + + + ); +}; + +export default MikroModule; diff --git a/src/mikro/MikroProvider.tsx b/src/mikro/MikroProvider.tsx index 05ea2c2..28eba5b 100644 --- a/src/mikro/MikroProvider.tsx +++ b/src/mikro/MikroProvider.tsx @@ -1,41 +1,41 @@ import { ApolloClient, NormalizedCacheObject } from "@apollo/client"; import React, { useState } from "react"; -import { createMikroClient } from "./client"; import { MikroContext } from "./MikroContext"; +import { createMikroClient } from "./client"; import { MikroConfig } from "./types"; export type MikroProps = { children: React.ReactNode; }; -export const MikroProvider: React.FC = ({ children }) => { - const [client, setClient] = useState< - ApolloClient | undefined - >(); - const [config, setConfig] = useState(); +export type ConfigState = { + config?: MikroConfig; + client?: ApolloClient; +}; - const configure = (config: MikroConfig) => { - setConfig(config); - setClient(createMikroClient(config)); - }; +export const MikroProvider: React.FC = ({ children }) => { + const [config, setConfig] = useState({ + config: undefined, + client: undefined, + }); - const s3resolve = (path?: string | null) => { - if (config) { - return config.s3resolve(path); + const configure = (config?: MikroConfig) => { + if (!config) { + setConfig({ + config: undefined, + client: undefined, + }); + return; } - return "fallback"; - }; - - + setConfig({ config: config, client: createMikroClient(config) }); + }; return ( {children} diff --git a/src/mikro/api/graphql.ts b/src/mikro/api/graphql.ts index e43c961..30d2051 100644 --- a/src/mikro/api/graphql.ts +++ b/src/mikro/api/graphql.ts @@ -175,7 +175,8 @@ export type Comment = { parent?: Maybe; resolved?: Maybe; resolvedBy?: Maybe; - text: Scalars['String']; + /** The text of the comment (without any formatting) */ + text?: Maybe; user: User; }; @@ -2519,6 +2520,7 @@ export type OmeroViewsArgs = { activeForY?: InputMaybe; activeForZ?: InputMaybe; ids?: InputMaybe>>; + isGlobal?: InputMaybe; limit?: InputMaybe; name?: InputMaybe; offset?: InputMaybe; @@ -3074,6 +3076,14 @@ export type Query = { /** My samples return all of the users samples attached to the current user */ graphs?: Maybe>>; hello?: Maybe; + /** + * Get a single Image by ID + * + * Returns a single Representation by ID. If the user does not have access + * to the Representation, an error will be raised. + * + */ + image?: Maybe; /** * Get a single instrumes by ID * @@ -3783,6 +3793,12 @@ export type QueryGraphsArgs = { }; +/** The root Query */ +export type QueryImageArgs = { + id: Scalars['ID']; +}; + + /** The root Query */ export type QueryInstrumentArgs = { id?: InputMaybe; @@ -4535,6 +4551,7 @@ export type QueryViewsArgs = { activeForY?: InputMaybe; activeForZ?: InputMaybe; ids?: InputMaybe>>; + isGlobal?: InputMaybe; limit?: InputMaybe; name?: InputMaybe; offset?: InputMaybe; @@ -4723,6 +4740,8 @@ export type Representation = { variety: RepresentationVariety; /** The rendered bioimages */ videos: Array