Skip to content

Commit

Permalink
add to deinstall that it will not lead to a content state with unreso…
Browse files Browse the repository at this point in the history
…lved dependencies
  • Loading branch information
gynt committed Aug 16, 2024
1 parent 133d421 commit 0c4fdcd
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import { uninstallContents } from './callbacks/uninstall-content';
import { showModalOkCancel } from '../../../modals/modal-ok-cancel';
import Logger from '../../../../util/scripts/logging';
import { getStore } from '../../../../hooks/jotai/base';
import { ExtensionDependencyTree } from '../../../../function/extensions/dependency-management/dependency-resolution';
import {
EXTENSIONS_ATOM,
EXTENSIONS_STATE_TREE_ATOM,
} from '../../../../function/extensions/state/focus';

const LOGGER = new Logger('uninstall-button.tsx');

Expand Down Expand Up @@ -86,7 +91,43 @@ export function UninstallButton(
}

if (busyCount > 0) {
// TODO:
// TODO: fixed elsewhere
}

const extensions = getStore().get(EXTENSIONS_ATOM);
const toBeRemovedExtensions = installed.map(
(ce) =>
extensions.filter(
(ext) =>
ext.name === ce.definition.name &&
ext.version === ce.definition.version,
)[0],
);
const leftOverExtensions = extensions.filter(
(ext) => toBeRemovedExtensions.indexOf(ext) === -1,
);
const etree = getStore().get(EXTENSIONS_STATE_TREE_ATOM);
const tree = new ExtensionDependencyTree(
leftOverExtensions,
etree.frontendVersion,
etree.frameworkVersion,
);

const solution = tree.tryResolveAllDependencies();

if (solution.status !== 'ok') {
const okCancelResult = await showModalOkCancel({
title: 'Removal of dependencies',
message:
'Deinstallation of the selected content will lead to unresolved dependencies.\n\nAre you sure you want to uninstall the selected?',
});
if (okCancelResult === false) {
getStore().set(
CONTENT_TAB_LOCK,
getStore().get(CONTENT_TAB_LOCK) - 1,
);
return;
}
}

getStore().set(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
CONTENT_INTERFACE_STATE_ATOM,
contentInstallationStatusAtoms,
filteredContentElementsAtom,
isContentInUseAtom,
} from '../state/atoms';
import { ContentElement } from '../../../../function/content/types/content-element';
import { STATUS_BAR_MESSAGE_ATOM } from '../../../footer/footer';
Expand Down Expand Up @@ -69,6 +70,16 @@ export function ContentElementView(props: ContentElementViewProps) {

const setStatusBarMessage = useSetAtom(STATUS_BAR_MESSAGE_ATOM);

const isInUseAtom = useMemo(
() =>
atom(
(get) =>
get(isContentInUseAtom).filter((iuce) => iuce === data).length > 0,
),
[data],
);
const isInUse = useAtomValue(isInUseAtom);

const statusElementAtom = useMemo(
() =>
atom((get) => {
Expand Down Expand Up @@ -148,6 +159,7 @@ export function ContentElementView(props: ContentElementViewProps) {
<CheckCircleFill
style={{
color: 'darkgreen',
opacity: isInUse ? '50%' : '100%',
}}
onMouseEnter={() => {
setStatusBarMessage(
Expand Down Expand Up @@ -182,7 +194,7 @@ export function ContentElementView(props: ContentElementViewProps) {
}
return statusElement;
}),
[id, isInstalled, isOnline, setStatusBarMessage],
[id, isInstalled, isOnline, isInUse, setStatusBarMessage],
);

const statusElement = useAtomValue(statusElementAtom);
Expand Down Expand Up @@ -255,17 +267,6 @@ export function ContentElementView(props: ContentElementViewProps) {

const progressOverlayElement = useAtomValue(progressOverlayElementAtom);

const isInUseAtom = useMemo(
() =>
atom(
(get) =>
get(ACTIVE_EXTENSIONS_ID_ATOM).filter((aeid) => aeid === id).length >
0,
),
[id],
);
const isInUse = useAtomValue(isInUseAtom);

return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div
Expand All @@ -284,9 +285,11 @@ export function ContentElementView(props: ContentElementViewProps) {
}
}
onMouseEnter={() => {
setStatusBarMessage(
`Cannot select content as it is an activated extension. Deactivate it before uninstalling: ${name}`,
);
if (isInUse) {
setStatusBarMessage(
`Cannot select content as it is an activated extension. Deactivate it before uninstalling: ${name}`,
);
}
}}
onMouseLeave={() => {
setStatusBarMessage(undefined);
Expand Down
29 changes: 29 additions & 0 deletions src/components/ucp-tabs/content-manager/state/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import { ContentInstallationStatus } from './downloads/download-progress';
import { UCP_VERSION_ATOM } from '../../../../function/ucp-files/ucp-version';
import { SHOW_ALL_EXTENSIONS_ATOM } from '../../../../function/gui-settings/settings';
import { UI_FILTER_SETTING_ATOM } from '../buttons/filter-button';
import {
ACTIVE_EXTENSIONS_ID_ATOM,
EXTENSIONS_ATOM,
EXTENSIONS_STATE_TREE_ATOM,
} from '../../../../function/extensions/state/focus';

// eslint-disable-next-line import/prefer-default-export
export const CONTENT_STATE_ATOM = atom(DEFAULT_CONTENT_STATE);
Expand Down Expand Up @@ -176,3 +181,27 @@ export const filteredContentElementsAtom = atom((get) =>
)
.sort((a, b) => a.definition.name.localeCompare(b.definition.name)),
);

export const isContentInUseAtom = atom((get) =>
get(CONTENT_ELEMENTS_ATOM).filter(
(ce) =>
get(ACTIVE_EXTENSIONS_ID_ATOM).indexOf(
`${ce.definition.name}@${ce.definition.version}`,
) !== -1,
),
);

export const isTopLevelContentAtom = atom((get) =>
get(CONTENT_ELEMENTS_ATOM).filter((ce) => {
const tree = get(EXTENSIONS_STATE_TREE_ATOM);
const extensions = get(EXTENSIONS_ATOM);
const extOpt = extensions.filter(
(ext) =>
ext.name === ce.definition.name &&
ext.version === ce.definition.version,
);
if (extOpt.length === 0) return true;

return tree.reverseExtensionDependenciesFor(extOpt[0]).length === 0;
}),
);
10 changes: 10 additions & 0 deletions src/function/extensions/state/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,13 @@ export const ACTIVE_EXTENSIONS_ID_ATOM = atom<string[]>((get) => {
);
return result;
});

export const EXTENSIONS_STATE_TREE_ATOM = focusAtom(
EXTENSION_STATE_INTERFACE_ATOM,
(optic) => optic.prop('tree'),
);

export const EXTENSIONS_ATOM = focusAtom(
EXTENSION_STATE_INTERFACE_ATOM,
(optic) => optic.prop('extensions'),
);

0 comments on commit 0c4fdcd

Please sign in to comment.