Skip to content

Commit

Permalink
feat(publish): add meta and publish plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
soofstad committed Feb 15, 2024
1 parent d56b318 commit eea5411
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 5 deletions.
19 changes: 19 additions & 0 deletions packages/dm-core-plugins/blueprints/common/Meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "Meta",
"type": "CORE:Blueprint",
"extends": ["CORE:Entity"],
"description": "Purely for convenience. A wrapper that contains any entity. Used to render the 'meta' plugin around entities.",
"attributes": [
{
"name": "type",
"type": "CORE:BlueprintAttribute",
"attributeType": "string"
},
{
"name": "content",
"type": "CORE:BlueprintAttribute",
"attributeType": "object",
"optional": true
}
]
}
31 changes: 31 additions & 0 deletions packages/dm-core-plugins/blueprints/publish/PublishConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "PublishConfig",
"type": "CORE:Blueprint",
"attributes": [
{
"name": "type",
"type": "CORE:BlueprintAttribute",
"attributeType": "string"
},
{
"name": "publishDestination",
"type": "dmss://system/SIMOS/BlueprintAttribute",
"attributeType": "string",
"description": "A reference/Id to where the published copy should be added."
},
{
"name": "publishWrapper",
"type": "dmss://system/SIMOS/BlueprintAttribute",
"description": "A blueprint for which an entity of will serve as a wrapper for the published document",
"attributeType": "string",
"optional": true
},
{
"name": "publishWrapperAttribute",
"type": "dmss://system/SIMOS/BlueprintAttribute",
"description": "Name of attribute in the 'publishWrapper'-blueprint of which the document will be placed.",
"attributeType": "string",
"optional": true
}
]
}
25 changes: 25 additions & 0 deletions packages/dm-core-plugins/blueprints/publish/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "publish",
"type": "CORE:Package",
"isRoot": false,
"_meta_": {
"type": "CORE:Meta",
"version": "0.0.1",
"dependencies": [
{
"type": "CORE:Dependency",
"alias": "CORE",
"address": "system/SIMOS",
"version": "0.0.1",
"protocol": "dmss"
},
{
"type": "CORE:Dependency",
"alias": "PLUGINS",
"address": "system/Plugins",
"version": "0.0.1",
"protocol": "dmss"
}
]
}
}
14 changes: 14 additions & 0 deletions packages/dm-core-plugins/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,18 @@ export default ({
}))
),
},
'@development-framework/dm-core-plugins/meta': {
component: lazy(() =>
import('./meta/MetaPlugin').then((module) => ({
default: module.MetaPlugin,
}))
),
},
'@development-framework/dm-core-plugins/publish': {
component: lazy(() =>
import('./publish/PublishPlugin').then((module) => ({
default: module.PublishPlugin,
}))
),
},
} as TUiPluginMap)
89 changes: 89 additions & 0 deletions packages/dm-core-plugins/src/meta/MetaPlugin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {
EntityView,
IUIPlugin,
Loading,
TGenericObject,
TMeta,
useDocument,
} from '@development-framework/dm-core'
import { Table } from '@equinor/eds-core-react'
import { DateTime } from 'luxon'

export const MetaPlugin = (props: IUIPlugin) => {
const { document, isLoading, error } = useDocument<TGenericObject>(
props.idReference,
0
)

if (isLoading) return <Loading />

if (error) throw new Error(JSON.stringify(error, null, 2))

if (!document) return

const meta: TMeta = document._meta_

if (document.type !== 'dmss://system/Plugins/dm-core-plugins/common/Meta')
throw new Error(
'The meta plugin only supports entities of type "Meta" at this stage'
)

return (
<>
<Table className={'w-full'}>
<Table.Head>
<Table.Row>
<Table.Cell>Created by</Table.Cell>
<Table.Cell>Created time</Table.Cell>
<Table.Cell>Last modified by</Table.Cell>
<Table.Cell>Last modified time</Table.Cell>
</Table.Row>
</Table.Head>
<Table.Body>
<Table.Row>
<Table.Cell>{meta?.createdBy ?? '-'}</Table.Cell>
<Table.Cell>
{meta?.createdTimestamp
? DateTime.fromISO(meta.createdTimestamp).toLocaleString(
{
day: '2-digit',
month: '2-digit',
year: '2-digit',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23',
},
{ locale: 'nb' }
)
: '-'}
</Table.Cell>
<Table.Cell>{meta?.lastModifiedBy ?? '-'}</Table.Cell>
<Table.Cell>
{meta?.lastModifiedTimestamp
? DateTime.fromISO(meta.lastModifiedTimestamp).toLocaleString(
{
day: '2-digit',
month: '2-digit',
year: '2-digit',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23',
},
{ locale: 'nb' }
)
: '-'}
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
{/*This empty div wrapper is kind of a hack to avoid EntityView take the same height as the entire plugin*/}
<div>
<EntityView
{...props}
type={document.content.type}
idReference={`${props.idReference}.content`}
/>
</div>
</>
)
}
53 changes: 53 additions & 0 deletions packages/dm-core-plugins/src/publish/PublishPlugin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
CopyLinkDialog,
EntityView,
IUIPlugin,
} from '@development-framework/dm-core'
import { Button, Icon } from '@equinor/eds-core-react'
import { approve } from '@equinor/eds-icons'
import { useState } from 'react'

export const PublishPlugin = (
props: IUIPlugin & {
config: {
publishDestination: string
publishWrapper?: string
publishWrapperAttribute?: string
}
}
) => {
const { idReference } = props
const [showPublishDialog, setShowPublishDialog] = useState<boolean>(false)

return (
<div className={'flex flex-col'}>
<div className={'justify-end flex'}>
<Button
variant='outlined'
color='secondary'
onClick={() => setShowPublishDialog(true)}
>
Publish
<Icon data={approve} />
</Button>
<CopyLinkDialog
title={'Publish report?'}
buttonText={'Publish'}
destination={props.config.publishDestination}
mode={'copy'}
// Defaults to using a "Meta"-entity as a wrapper. Can be overridden with config
wrapper={
props.config.publishWrapper ||
'dmss://system/Plugins/dm-core-plugins/common/Meta'
}
wrapperAttribute={props.config.publishWrapperAttribute || 'content'}
hideProvidedFields={true}
idReference={idReference}
open={showPublishDialog}
setOpen={setShowPublishDialog}
/>
</div>
<EntityView {...props} />
</div>
)
}
31 changes: 26 additions & 5 deletions packages/dm-core/src/components/CopyLinkDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '../index'
import { setMetaInDocument } from '../utils/setMetaInDocument'

type TProps = {
type TPropsBase = {
idReference: string
open: boolean
setOpen: (v: boolean) => void
Expand All @@ -27,6 +27,13 @@ type TProps = {
hideProvidedFields?: boolean
}

type TProps =
| (TPropsBase & { wrapper?: undefined; wrapperAttribute?: undefined })
| (TPropsBase & {
wrapper: string
wrapperAttribute: string
})

export const CopyLinkDialog = (props: TProps) => {
const {
idReference,
Expand All @@ -37,6 +44,8 @@ export const CopyLinkDialog = (props: TProps) => {
hideProvidedFields,
title,
buttonText,
wrapper,
wrapperAttribute,
} = props
const { tokenData } = useContext(AuthContext)

Expand All @@ -62,7 +71,7 @@ export const CopyLinkDialog = (props: TProps) => {
const [isLoading, setIsLoading] = useState<boolean>(false)
const dmss = useDMSS()

const copyEntityToDestination = () => {
const copyEntityToDestination = async () => {
if (!selectedDestination) return
setIsLoading(true)
let newDocument = window.structuredClone(document) as TValidEntity
Expand All @@ -79,20 +88,32 @@ export const CopyLinkDialog = (props: TProps) => {

newDocument = setMetaInDocument(newDocument, username)

if (wrapper) {
const wrapperEntity: TValidEntity =
// TODO: Handle relative/unresolved addresses? Perhaps in blueprint upload?
(await dmss.instantiateEntity({ entity: { type: wrapper } }))
.data as TValidEntity
wrapperEntity[wrapperAttribute] = newDocument
wrapperEntity._meta_ = newDocument._meta_
newDocument = wrapperEntity
}

dmss
.documentAdd({
address: selectedDestination.address,
document: JSON.stringify(newDocument),
})
.then(() => {
toast.success(`Entity copied to '${selectedDestination.path}'`)
setOpen(false)
})
.catch((error: AxiosError<ErrorResponse>) => {
console.error(error)
toast.error(error.response?.data.message)
})
.finally(() => setIsLoading(false))
.finally(() => {
setOpen(false)
setIsLoading(false)
})
}

const insertLinkAtDestination = () => {
Expand Down Expand Up @@ -120,7 +141,7 @@ export const CopyLinkDialog = (props: TProps) => {
}

return (
<Dialog open={open} style={{ minWidth: '20vw' }}>
<Dialog open={open} style={{ minWidth: '230px' }}>
<Dialog.Header>
<Dialog.Title>{title || 'Copy or link entity'}</Dialog.Title>
</Dialog.Header>
Expand Down

0 comments on commit eea5411

Please sign in to comment.