Skip to content

Commit

Permalink
Globally synced settings (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms authored Sep 4, 2023
1 parent 7fc8161 commit 9c0cf06
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 20 deletions.
7 changes: 7 additions & 0 deletions frontend/src/framework/Module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ export class Module<StateType extends StateBaseType> {
return this._syncableSettingKeys;
}


hasSyncableSettingKey(key: SyncSettingKey): boolean {
return this._syncableSettingKeys.includes(key);
}


makeInstance(instanceNumber: number): ModuleInstance<StateType> {

if (!this._workbench) {
throw new Error("Module must be added to a workbench before making an instance");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,117 @@ import { SyncSettingKey, SyncSettingsMeta } from "@framework/SyncSettings";
import { DrawerContent, Workbench } from "@framework/Workbench";
import { Drawer } from "@framework/internal/components/Drawer";
import { useActiveModuleId } from "@framework/internal/hooks/workbenchHooks";
import { LinkIcon } from "@heroicons/react/20/solid";
import { GlobeAltIcon, LinkIcon, MapPinIcon } from "@heroicons/react/20/solid";
import { Checkbox } from "@lib/components/Checkbox";

type ModulesListProps = {
workbench: Workbench;
};

export const SyncSettings: React.FC<ModulesListProps> = (props) => {
const forceRerender = React.useReducer((x) => x + 1, 0)[1];
const drawerContent = useStoreValue(props.workbench.getGuiStateStore(), "drawerContent");
const activeModuleId = useActiveModuleId(props.workbench);

const activeModuleInstance = props.workbench.getModuleInstance(activeModuleId);

const handleSyncSettingChange = (setting: SyncSettingKey, value: boolean) => {
function handleSyncSettingChange(setting: SyncSettingKey, value: boolean) {
if (activeModuleInstance === undefined) {
return;
}

if (value) {
activeModuleInstance.addSyncedSetting(setting);
if (!activeModuleInstance.isSyncedSetting(setting)) {
activeModuleInstance.addSyncedSetting(setting);
}
} else {
activeModuleInstance.removeSyncedSetting(setting);
}
};

forceRerender();
}

function handleGlobalSyncSettingChange(setting: SyncSettingKey, value: boolean) {
const moduleInstances = props.workbench.getModuleInstances();

// @rmt: This has to be changed as soon as we support multiple pages
for (const moduleInstance of moduleInstances) {
if (moduleInstance.getModule().hasSyncableSettingKey(setting)) {
if (value) {
if (!moduleInstance.isSyncedSetting(setting)) {
moduleInstance.addSyncedSetting(setting);
}
} else {
moduleInstance.removeSyncedSetting(setting);
}
}
}

forceRerender();
}

function isGlobalSyncSetting(setting: SyncSettingKey): boolean {
const moduleInstances = props.workbench.getModuleInstances();

// @rmt: This has to be changed as soon as we support multiple pages
for (const moduleInstance of moduleInstances) {
if (moduleInstance.getModule().hasSyncableSettingKey(setting)) {
if (!moduleInstance.isSyncedSetting(setting)) {
return false;
}
}
}

return true;
}

return (
<Drawer title="Sync settings" icon={<LinkIcon />} visible={drawerContent === DrawerContent.SyncSettings}>
{activeModuleId === "" || activeModuleInstance === undefined ? (
<div className="text-gray-500">No module selected</div>
) : (
<>
{activeModuleInstance
.getModule()
.getSyncableSettingKeys()
.map((setting) => {
return (
<div className="mb-2" key={`${activeModuleInstance.getId()}-${setting}`}>
<Checkbox
checked={activeModuleInstance.isSyncedSetting(setting)}
onChange={(e) => handleSyncSettingChange(setting, e.target.checked)}
label={SyncSettingsMeta[setting].name}
/>
</div>
);
})}
</>
<table className="w-full">
<thead>
<tr className="border-b">
<th className="border-r p-2 w-6">
<GlobeAltIcon className="w-4 h-4" title="Sync for all module instances" />
</th>
<th className="border-r p-2 w-6">
<MapPinIcon className="w-4 h-4" title="Sync for active module instance" />
</th>
<th></th>
</tr>
</thead>
<tbody>
{activeModuleInstance
.getModule()
.getSyncableSettingKeys()
.map((setting) => {
const globallySynced = isGlobalSyncSetting(setting);
return (
<tr key={setting} className="hover:bg-blue-50">
<td className="border-r p-2">
<Checkbox
checked={globallySynced}
onChange={(e) =>
handleGlobalSyncSettingChange(setting, e.target.checked)
}
/>
</td>
<td className="border-r p-2">
<Checkbox
checked={
globallySynced || activeModuleInstance.isSyncedSetting(setting)
}
onChange={(e) => handleSyncSettingChange(setting, e.target.checked)}
/>
</td>
<td className="p-2">{SyncSettingsMeta[setting].name}</td>
</tr>
);
})}
</tbody>
</table>
)}
</Drawer>
);
Expand Down

0 comments on commit 9c0cf06

Please sign in to comment.