Skip to content

Commit

Permalink
support multiple visual link targets
Browse files Browse the repository at this point in the history
  • Loading branch information
heswell committed Sep 7, 2024
1 parent 2d2ae38 commit 000a4e5
Show file tree
Hide file tree
Showing 20 changed files with 124 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class ArrayDataSource
viewport,
}: ArrayDataSourceConstructorProps) {
super();

console.log(`ArrayDataSource #${viewport}`);
if (!data || !columnDescriptors) {
throw Error(
"ArrayDataSource constructor called without data or without columnDescriptors",
Expand Down Expand Up @@ -700,8 +700,9 @@ export class ArrayDataSource
return this.#title ?? `${this.table.module} ${this.table.table}`;
}

set title(title: string | undefined) {
set title(title: string) {
this.#title = title;
this.emit("title-changed", this.viewport, title);
}

get _clientCallback() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,10 @@ export class JsonDataSource
}

get title() {
return this.#title;
return this.#title ?? "";
}

set title(title: string | undefined) {
set title(title: string) {
this.#title = title;
}

Expand Down
9 changes: 6 additions & 3 deletions vuu-ui/packages/vuu-data-remote/src/vuu-data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class VuuDataSource

this.bufferSize = bufferSize;
this.table = table;
this.viewport = viewport;
this.viewport = viewport ?? "";

this.#config = {
...this.#config,
Expand All @@ -126,7 +126,7 @@ export class VuuDataSource

async subscribe(
{
viewport = this.viewport ?? (this.viewport = uuid()),
viewport = this.viewport || (this.viewport = uuid()),
columns,
aggregations,
range,
Expand Down Expand Up @@ -605,15 +605,18 @@ export class VuuDataSource
return this.#title ?? `${this.table.module} ${this.table.table}`;
}

set title(title: string | undefined) {
set title(title: string) {
this.#title = title;
if (this.viewport && title) {
// This message doesn't actually trigger a message to Vuu server
// it will be used to recompute visual link labels
this.server?.send({
type: "setTitle",
title,
viewport: this.viewport,
});
}
this.emit("title-changed", this.viewport ?? "'", title);
}

get visualLink() {
Expand Down
40 changes: 23 additions & 17 deletions vuu-ui/packages/vuu-data-test/src/VuuModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ export class VuuModule<T extends string = string> implements IVuuModule<T> {
}

private unregisterViewport = (viewportId: string) => {
console.log(`<subscription-closed> unregister viewport ${viewportId}`);

for (const [tableName, subscriptions] of this.#subscriptionMap) {
if (subscriptions[0].viewportId.toString() === viewportId) {
this.#subscriptionMap.delete(tableName);
Expand Down Expand Up @@ -133,21 +131,22 @@ export class VuuModule<T extends string = string> implements IVuuModule<T> {
throw Error(`getSubscribedDataSource #${vpId} not in subscriptionMap`);
}

getLink = (
getLinks = (
subscriptionMap: Map<string, Subscription[]>,
vuuLinks: VuuLink[],
) => {
const visualLinks: LinkDescriptorWithLabel[] = [];
for (let i = 0; i < vuuLinks.length; i++) {
if (subscriptionMap.get(vuuLinks[i].toTable)) {
const newLink: LinkDescriptorWithLabel = {
parentClientVpId: subscriptionMap.get(vuuLinks[i].toTable)?.[0]
.viewportId as string,
parentVpId: subscriptionMap.get(vuuLinks[i].toTable)?.[0]
.viewportId as string,
link: vuuLinks[i],
};
visualLinks.push(newLink);
const subscriptions = subscriptionMap.get(vuuLinks[i].toTable);
if (subscriptions) {
subscriptions.forEach(({ viewportId }) => {
const newLink: LinkDescriptorWithLabel = {
parentClientVpId: viewportId,
parentVpId: viewportId,
link: vuuLinks[i],
};
visualLinks.push(newLink);
});
}
}
return visualLinks;
Expand Down Expand Up @@ -198,7 +197,7 @@ export class VuuModule<T extends string = string> implements IVuuModule<T> {
const visualLinks =
this.#visualLinks?.[tableName] === undefined
? undefined
: this.getLink(
: this.getLinks(
this.#subscriptionMap,
this.#visualLinks[tableName] as VuuLink[],
);
Expand All @@ -223,13 +222,20 @@ export class VuuModule<T extends string = string> implements IVuuModule<T> {

dataSource.on("unsubscribed", this.unregisterViewport);

this.#subscriptionMap.set(tableName, [
{ viewportId: dataSource.viewport as string, dataSource },
]);
const existingSubscriptions = this.#subscriptionMap.get(tableName);
const subscription = {
viewportId: dataSource.viewport as string,
dataSource,
};
if (existingSubscriptions) {
existingSubscriptions.push(subscription);
} else {
this.#subscriptionMap.set(tableName, [subscription]);
}

for (const key of this.#subscriptionMap.keys()) {
if (this.#visualLinks?.[key as T] && key !== tableName) {
const vLink = this.getLink(
const vLink = this.getLinks(
this.#subscriptionMap,
this.#visualLinks?.[key as T] as VuuLink[],
);
Expand Down
3 changes: 2 additions & 1 deletion vuu-ui/packages/vuu-data-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ export type DataSourceEvents = {
unsubscribed: DataSourceEventHandler;
disabled: DataSourceEventHandler;
enabled: DataSourceEventHandler;
"title-changed": (id: string, title: string) => void;
"visual-link-created": (message: DataSourceVisualLinkCreatedMessage) => void;
"visual-link-removed": () => void;
};
Expand Down Expand Up @@ -507,7 +508,7 @@ export interface DataSource
* Users can edit titles on components. If so, and this is a table component, we will display this title in
* the context menu rather than the underlying table name (which may not be unique within the layout)
*/
title?: string;
title: string;
unsubscribe: () => void;
viewport?: string;
visualLink?: LinkDescriptorWithLabel;
Expand Down
16 changes: 8 additions & 8 deletions vuu-ui/packages/vuu-layout/src/layout-header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const Header = ({
originalValue = "",
finalValue = "",
allowDeactivation = true,
editCancelled = false
editCancelled = false,
) => {
setEditing(false);
if (editCancelled) {
Expand Down Expand Up @@ -113,7 +113,7 @@ export const Header = ({
break;
default:
postTitleContributedItems.push(
cloneElement(contribution.content, { key: i })
cloneElement(contribution.content, { key: i }),
);
}
});
Expand All @@ -130,8 +130,7 @@ export const Header = ({
onExitEditMode={handleExitEditMode}
onKeyDown={handleTitleKeyDown}
ref={labelFieldRef}
tabIndex={0}
/>
/>,
);

allowRename &&
Expand All @@ -143,8 +142,9 @@ export const Header = ({
key="edit-button"
onClick={handleClickEdit}
onMouseDown={handleButtonMouseDown}
tabIndex={0}
variant="secondary"
/>
/>,
);

closeable &&
Expand All @@ -156,21 +156,21 @@ export const Header = ({
onClick={handleClose}
onMouseDown={handleButtonMouseDown}
variant="secondary"
/>
/>,
);

postTitleContributedItems.length > 0 &&
toolbarItems.push(
<div data-align="end" key="contributions">
{postTitleContributedItems}
</div>
</div>,
);

actionButtons.length > 0 &&
toolbarItems.push(
<div data-align="end" key="actions">
{actionButtons}
</div>
</div>,
);

return (
Expand Down
9 changes: 5 additions & 4 deletions vuu-ui/packages/vuu-layout/src/layout-view/View.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const getProps = (state?: Props, props?: Props) => {
*/
const View = forwardRef(function View(
props: ViewProps,
forwardedRef: ForwardedRef<HTMLDivElement>
forwardedRef: ForwardedRef<HTMLDivElement>,
) {
const {
Header = VuuHeader,
Expand Down Expand Up @@ -73,6 +73,7 @@ const View = forwardRef(function View(
});

const id = useId(idProp);

const rootRef = useRef<HTMLDivElement>(null);
const mainRef = useRef<HTMLDivElement>(null);
const [componentProps, _setComponentProps] = useState<Props>();
Expand Down Expand Up @@ -106,7 +107,7 @@ const View = forwardRef(function View(
if (React.isValidElement(children) && (restoredState || componentProps)) {
return React.cloneElement(
children,
getProps(restoredState, componentProps)
getProps(restoredState, componentProps),
);
}
return children;
Expand Down Expand Up @@ -138,7 +139,7 @@ const View = forwardRef(function View(
saveSession,
setComponentProps,
title,
]
],
);

const headerProps = typeof header === "object" ? header : {};
Expand Down Expand Up @@ -185,7 +186,7 @@ interface ViewComponentType {
(
props: ViewProps & {
ref?: ForwardedRef<HTMLDivElement>;
}
},
): ReactElement<ViewProps>;
displayName?: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type BroadcastMessageHandler = (message: ViewBroadcastMessage) => void;
const isMessageForSelf = (
message: ViewBroadcastMessage,
id?: string,
path?: string
path?: string,
) => {
if (id && message.targetId === id) {
return true;
Expand All @@ -25,7 +25,7 @@ const isMessageForSelf = (
export const useViewBroadcastChannel = (
id?: string,
path?: string,
onMessageReceived?: BroadcastMessageHandler
onMessageReceived?: BroadcastMessageHandler,
) => {
const broadcastChannelRef =
useRef<VuuBroadcastChannel<ViewBroadcastMessage>>();
Expand All @@ -34,6 +34,7 @@ export const useViewBroadcastChannel = (
const broadcastChannel: VuuBroadcastChannel<ViewBroadcastMessage> =
new BroadcastChannel("vuu");
broadcastChannel.onmessage = (evt) => {
console.log(`message received by ${id}`);
if (isMessageForSelf(evt.data, id, path)) {
onMessageReceived?.(evt.data);
}
Expand All @@ -46,6 +47,9 @@ export const useViewBroadcastChannel = (
}, [id, onMessageReceived, path]);

const sendMessage = useCallback((message: ViewBroadcastMessage) => {
console.log(`send message from ${id} to ${message.targetId}`, {
message,
});
broadcastChannelRef.current?.postMessage(message);
}, []);

Expand Down
1 change: 0 additions & 1 deletion vuu-ui/packages/vuu-theme/css/components/header.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.salt-theme.vuu-theme {
.vuuHeader-title {
height: 100%;
border-bottom: solid 2px var(--vuu-color-purple-10);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,40 @@
display: flex;
flex-direction: column;
font-size: var(--salt-text-fontSize);
height: var(--editableLabel-height);
height: 100%;
justify-content: center;
letter-spacing: normal;

/* max-width: 170px; */
overflow: hidden;
padding: 0 var(--editableLabel-padding);
padding-right: var(--editableLabel-padding);
position: relative;
text-overflow: ellipsis;
white-space: nowrap;
z-index: var(--salt-zIndex-default);

&:focus,
&:focus-within {
outline: var(--salt-focused-outline);
}

&[data-embedded] {
outline: none;
}
}

.vuuEditableLabel:before {
box-sizing: content-box;
content: attr(data-text);
display: block;
height: 0px;
padding: 0 var(--salt-spacing-200);
visibility: hidden;
white-space: pre-wrap;
}

.vuuEditableLabel .saltInput {
font-weight: var(--salt-text-fontWeight);
left: var(--editableLabel-padding, 0);
padding: 0;
outline-style: none;
position: absolute;
padding: 0 var(--salt-spacing-100);
right: var(--editableLabel-padding, 0);
top: var(--saltEditableLabel-top, 1px);
width: auto;
width: calc(100% - 4px);
}

.vuuEditableLabel .saltInput-activationIndicator {
Expand All @@ -72,6 +67,7 @@

.vuuEditableLabel-label {
overflow: hidden;
padding-left: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
Loading

0 comments on commit 000a4e5

Please sign in to comment.