diff --git a/CHANGELOG.md b/CHANGELOG.md
index 13fa77b5f..258313f5a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Added links instead of imperative navigation with onClick - #1969 by @taniotanio7
- Fixed clearing attribute values - #2047 by @witoszekdev
- Fixed EditorJS integration in RichTextEditor input - #2052 by @witoszekdev
+- Improvements to the app list page: added toggle and permision preview - #2035 by @witoszekdev
- Added links to table pagination buttons - #2063 by @witoszekdev
- Using push instead of replace to history stack for pagination navigation - #2063 by @witoszekdev
diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json
index 9a05135e6..32bbffc12 100644
--- a/locale/defaultMessages.json
+++ b/locale/defaultMessages.json
@@ -86,6 +86,9 @@
"context": "error message",
"string": "This attribute is already assigned."
},
+ "+iV0gu": {
+ "string": "Internal Apps"
+ },
"+iVKR1": {
"context": "assign attribute value button",
"string": "Assign value"
@@ -1658,6 +1661,10 @@
"BtErCZ": {
"string": "Search Plugins..."
},
+ "BvmnJq": {
+ "context": "section header",
+ "string": "Third Party Apps"
+ },
"Bx367s": {
"context": "product is hidden",
"string": "Hidden"
@@ -2760,10 +2767,6 @@
"context": "filtering option",
"string": "All Warehouses"
},
- "JufWFT": {
- "context": "app installation error",
- "string": "There was a problem during installation"
- },
"Jwuu4X": {
"context": "select product informations to be exported",
"string": "Information exported:"
@@ -3930,10 +3933,6 @@
"context": "order subtotal price",
"string": "Subtotal"
},
- "TBaMo2": {
- "context": "about app",
- "string": "About"
- },
"TC/EOG": {
"context": "status section title",
"string": "Status in channel"
@@ -4596,6 +4595,10 @@
"context": "filters error messages value required",
"string": "Choose a value"
},
+ "Xl0o2y": {
+ "context": "app installation error",
+ "string": "Problem occured during installation"
+ },
"XlPKAR": {
"context": "WarehouseSettings private stock description",
"string": "If enabled stock in this warehouse won't be shown"
@@ -4809,10 +4812,6 @@
"context": "subsection header",
"string": "Shipping Address"
},
- "ZeD2TK": {
- "context": "section header",
- "string": "Third-party Apps"
- },
"Zg0dRo": {
"context": "dialog description",
"string": "You have changed customer assigned to this order. What would you like to do with the shipping address?"
@@ -7505,9 +7504,6 @@
"context": "section header",
"string": "Plugin Information and Status"
},
- "w4R/SO": {
- "string": "Local Apps"
- },
"w6Gau0": {
"context": "deactivate named app",
"string": "Are you sure you want to disable {name}? Your data will be kept until you reactivate the app. You will be still billed for the app."
@@ -7630,6 +7626,10 @@
"xJQX5t": {
"string": "No staff members found"
},
+ "xNfh4L": {
+ "context": "app permissions tooltip header",
+ "string": "App permissions"
+ },
"xOEZjV": {
"context": "attribute's label",
"string": "Default Label"
diff --git a/src/apps/components/AppPermissions/AppPermissions.tsx b/src/apps/components/AppPermissions/AppPermissions.tsx
new file mode 100644
index 000000000..4a388acf8
--- /dev/null
+++ b/src/apps/components/AppPermissions/AppPermissions.tsx
@@ -0,0 +1,49 @@
+import { AppPermissionFragment } from "@saleor/graphql";
+import {
+ IconButton,
+ makeStyles,
+ PermissionsIcon,
+ Tooltip
+} from "@saleor/macaw-ui";
+import React from "react";
+import { FormattedMessage } from "react-intl";
+
+const useStyles = makeStyles(
+ () => ({
+ list: {
+ margin: 0,
+ paddingLeft: "16px"
+ }
+ }),
+ { name: "AppPermissions" }
+);
+
+interface AppPermissionsProps {
+ permissions: AppPermissionFragment[];
+}
+
+export const AppPermissions = ({ permissions }: AppPermissionsProps) => {
+ const classes = useStyles();
+ return (
+
+ }
+ title={
+
+ {permissions.map(permission => (
+ {permission.name}
+ ))}
+
+ }
+ >
+
+
+
+
+ );
+};
diff --git a/src/apps/components/AppsInProgress/AppsInProgress.tsx b/src/apps/components/AppsInProgress/AppsInProgress.tsx
index eca023e02..e9aa9c4e1 100644
--- a/src/apps/components/AppsInProgress/AppsInProgress.tsx
+++ b/src/apps/components/AppsInProgress/AppsInProgress.tsx
@@ -4,16 +4,20 @@ import {
TableBody,
TableCell,
TableRow,
- Tooltip,
Typography
} from "@material-ui/core";
-import ErrorIcon from "@material-ui/icons/Error";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle";
import { IconButton } from "@saleor/components/IconButton";
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
import { AppsInstallationsQuery, JobStatusEnum } from "@saleor/graphql";
-import { DeleteIcon, ResponsiveTable } from "@saleor/macaw-ui";
+import {
+ DeleteIcon,
+ Indicator,
+ ResponsiveTable,
+ Tooltip,
+ TooltipMountWrapper
+} from "@saleor/macaw-ui";
import { renderCollection } from "@saleor/misc";
import classNames from "classnames";
import React from "react";
@@ -82,17 +86,14 @@ const AppsInProgress: React.FC = ({
>
- {message} }
- classes={{
- tooltip: classes.customTooltip
- }}
- >
-
+
+
+
+
diff --git a/src/apps/components/AppsListPage/AppListPage.stories.tsx b/src/apps/components/AppsListPage/AppListPage.stories.tsx
index 37362e985..bd182c9fc 100644
--- a/src/apps/components/AppsListPage/AppListPage.stories.tsx
+++ b/src/apps/components/AppsListPage/AppListPage.stories.tsx
@@ -1,3 +1,4 @@
+import { AppListContext } from "@saleor/apps/context";
import {
listActionsProps,
pageListProps,
@@ -36,6 +37,13 @@ const props: AppsListPageProps = {
storiesOf("Views / Apps / Apps list", module)
.addDecorator(Decorator)
+ .addDecorator(story => (
+ undefined, deactivateApp: () => undefined }}
+ >
+ {story()}
+
+ ))
.addDecorator(PaginatorContextDecorator)
.add("default", () => )
.add("loading", () => (
diff --git a/src/apps/components/AppsListPage/AppsListPage.tsx b/src/apps/components/AppsListPage/AppsListPage.tsx
index ac11b9990..568ab84a5 100644
--- a/src/apps/components/AppsListPage/AppsListPage.tsx
+++ b/src/apps/components/AppsListPage/AppsListPage.tsx
@@ -10,7 +10,6 @@ import { useIntl } from "react-intl";
import AppsInProgress from "../AppsInProgress/AppsInProgress";
import CustomApps from "../CustomApps/CustomApps";
import InstalledApps from "../InstalledApps/InstalledApps";
-import Marketplace from "../Marketplace";
export interface AppsListPageProps extends ListProps {
installedAppsList: AppsListQuery["apps"]["edges"];
@@ -43,17 +42,6 @@ const AppsListPage: React.FC = ({
return (
- {!!appsInProgress?.length && (
- <>
-
-
- >
- )}
= ({
getCustomAppHref={getCustomAppHref}
onRemove={onCustomAppRemove}
/>
-
-
+ {!!appsInProgress?.length && (
+ <>
+
+
+ >
+ )}
);
};
diff --git a/src/apps/components/InstalledApps/InstalledApps.tsx b/src/apps/components/InstalledApps/InstalledApps.tsx
index e7372aec1..e00921c74 100644
--- a/src/apps/components/InstalledApps/InstalledApps.tsx
+++ b/src/apps/components/InstalledApps/InstalledApps.tsx
@@ -1,19 +1,18 @@
import {
Card,
+ Switch,
TableBody,
TableCell,
- TableFooter,
TableRow,
Typography
} from "@material-ui/core";
-import { appDetailsUrl, appUrl } from "@saleor/apps/urls";
-import { Button } from "@saleor/components/Button";
+import { useAppListContext } from "@saleor/apps/context";
+import { appUrl } from "@saleor/apps/urls";
import CardTitle from "@saleor/components/CardTitle";
import { IconButton } from "@saleor/components/IconButton";
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
-import { TablePaginationWithContext } from "@saleor/components/TablePagination";
import TableRowLink from "@saleor/components/TableRowLink";
-import { AppsListQuery } from "@saleor/graphql";
+import { AppListItemFragment, AppsListQuery } from "@saleor/graphql";
import { DeleteIcon, ResponsiveTable } from "@saleor/macaw-ui";
import { renderCollection } from "@saleor/misc";
import { ListProps } from "@saleor/types";
@@ -22,14 +21,13 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useStyles } from "../../styles";
+import { AppPermissions } from "../AppPermissions/AppPermissions";
import AppsSkeleton from "../AppsSkeleton";
-import DeactivatedText from "../DeactivatedText";
export interface InstalledAppsProps extends ListProps {
appsList: AppsListQuery["apps"]["edges"];
onRemove: (id: string) => void;
}
-const numberOfColumns = 2;
const InstalledApps: React.FC = ({
appsList,
@@ -41,26 +39,26 @@ const InstalledApps: React.FC = ({
}) => {
const intl = useIntl();
const classes = useStyles(props);
+ const { activateApp, deactivateApp } = useAppListContext();
+
+ const getHandleToggle = (app: AppListItemFragment) => () => {
+ if (app.isActive) {
+ deactivateApp(app.id);
+ } else {
+ activateApp(app.id);
+ }
+ };
return (
-
-
-
-
-
{renderCollection(
appsList,
@@ -75,11 +73,6 @@ const InstalledApps: React.FC = ({
{app.node.name}
- {!app.node.isActive && (
-
-
-
- )}
{app.node.appUrl && (
@@ -91,14 +84,12 @@ const InstalledApps: React.FC = ({
)}
-
-
-
+
+
void;
+ deactivateApp: (appId: string) => void;
+}
+
+export const AppListContext = React.createContext<
+ AppListContextValues | undefined
+>(undefined);
+
+export const useAppListContext = () => {
+ const context = React.useContext(AppListContext);
+
+ if (!context) {
+ throw new Error("useAppListContext must be used within a AppListContext");
+ }
+
+ return context;
+};
diff --git a/src/apps/fixtures.ts b/src/apps/fixtures.ts
index 1b4bd555b..563d379df 100644
--- a/src/apps/fixtures.ts
+++ b/src/apps/fixtures.ts
@@ -17,7 +17,14 @@ export const appsList: AppsListQuery["apps"]["edges"] = [
isActive: true,
name: "app",
type: AppTypeEnum.THIRDPARTY,
- appUrl: null
+ appUrl: null,
+ permissions: [
+ {
+ __typename: "Permission",
+ code: PermissionEnum.MANAGE_USERS,
+ name: "Manage customers."
+ }
+ ]
}
},
{
@@ -28,7 +35,19 @@ export const appsList: AppsListQuery["apps"]["edges"] = [
isActive: false,
name: "app1",
type: AppTypeEnum.THIRDPARTY,
- appUrl: "http://localhost:3000"
+ appUrl: "http://localhost:3000",
+ permissions: [
+ {
+ __typename: "Permission",
+ code: PermissionEnum.MANAGE_ORDERS,
+ name: "Manage orders."
+ },
+ {
+ __typename: "Permission",
+ code: PermissionEnum.MANAGE_USERS,
+ name: "Manage customers."
+ }
+ ]
}
}
];
@@ -42,7 +61,19 @@ export const customAppsList: AppsListQuery["apps"]["edges"] = [
isActive: true,
name: "app custom",
type: AppTypeEnum.LOCAL,
- appUrl: null
+ appUrl: null,
+ permissions: [
+ {
+ __typename: "Permission",
+ code: PermissionEnum.MANAGE_ORDERS,
+ name: "Manage orders."
+ },
+ {
+ __typename: "Permission",
+ code: PermissionEnum.MANAGE_USERS,
+ name: "Manage customers."
+ }
+ ]
}
}
];
diff --git a/src/apps/queries.ts b/src/apps/queries.ts
index 1588cf00e..a50c7a219 100644
--- a/src/apps/queries.ts
+++ b/src/apps/queries.ts
@@ -26,11 +26,7 @@ export const appsList = gql`
totalCount
edges {
node {
- id
- name
- isActive
- type
- appUrl
+ ...AppListItem
}
}
}
diff --git a/src/apps/styles.ts b/src/apps/styles.ts
index b10a9fab9..9d9d0c171 100644
--- a/src/apps/styles.ts
+++ b/src/apps/styles.ts
@@ -75,13 +75,12 @@ export const useStyles = makeStyles(
padding: "0!important"
},
error: {
- "& svg": {
- bottom: theme.spacing(0.2),
- marginLeft: theme.spacing(0.6),
- position: "relative"
+ "& button": {
+ marginLeft: theme.spacing(0.6)
},
color: theme.palette.error.main,
- margin: theme.spacing(0, 1, 0.7, 0)
+ marginRight: theme.spacing(1),
+ alignItems: "flex-end"
},
headerLinkContainer: {
"& svg": {
diff --git a/src/apps/urls.ts b/src/apps/urls.ts
index ca923dcb0..ca7d3292a 100644
--- a/src/apps/urls.ts
+++ b/src/apps/urls.ts
@@ -5,7 +5,12 @@ import { ActiveTab, Dialog, Pagination, SingleAction } from "../types";
export const MANIFEST_ATTR = "manifestUrl";
-export type AppListUrlDialog = "remove" | "remove-app" | "remove-custom-app";
+export type AppListUrlDialog =
+ | "remove"
+ | "remove-app"
+ | "remove-custom-app"
+ | "app-activate"
+ | "app-deactivate";
export type AppDetailsUrlDialog = "app-activate" | "app-deactivate";
diff --git a/src/apps/views/AppsList/AppsList.tsx b/src/apps/views/AppsList/AppsList.tsx
index 59ad5d052..441327760 100644
--- a/src/apps/views/AppsList/AppsList.tsx
+++ b/src/apps/views/AppsList/AppsList.tsx
@@ -1,13 +1,16 @@
import { useApolloClient } from "@apollo/client";
+import AppActivateDialog from "@saleor/apps/components/AppActivateDialog";
+import AppDeactivateDialog from "@saleor/apps/components/AppDeactivateDialog";
+import { AppListContext, AppListContextValues } from "@saleor/apps/context";
import {
- AppDeleteFailedInstallationMutation,
- AppDeleteMutation,
AppsInstallationsQuery,
AppsListQuery,
AppSortField,
AppTypeEnum,
JobStatusEnum,
OrderDirection,
+ useAppActivateMutation,
+ useAppDeactivateMutation,
useAppDeleteFailedInstallationMutation,
useAppDeleteMutation,
useAppRetryInstallMutation,
@@ -23,7 +26,6 @@ import usePaginator, {
PaginatorContext
} from "@saleor/hooks/usePaginator";
import { ListViews } from "@saleor/types";
-import getAppErrorMessage from "@saleor/utils/errors/app";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import React, { useEffect, useRef } from "react";
import { useIntl } from "react-intl";
@@ -131,17 +133,36 @@ export const AppsList: React.FC = ({ params }) => {
};
const [retryInstallApp] = useAppRetryInstallMutation({
onCompleted: data => {
- const errors = data.appRetryInstall.errors;
- if (!errors.length) {
+ if (!data?.appRetryInstall?.errors?.length) {
const appInstallation = data.appRetryInstall.appInstallation;
setActiveInstallations(installations => [
...installations,
{ id: appInstallation.id, name: appInstallation.appName }
]);
- } else {
- errors.forEach(error =>
- notify({ status: "error", text: getAppErrorMessage(error, intl) })
- );
+ }
+ }
+ });
+ const [activateApp, activateAppResult] = useAppActivateMutation({
+ onCompleted: data => {
+ if (!data?.appActivate?.errors?.length) {
+ notify({
+ status: "success",
+ text: intl.formatMessage(messages.appActivated)
+ });
+ refetch();
+ closeModal();
+ }
+ }
+ });
+ const [deactivateApp, deactivateAppResult] = useAppDeactivateMutation({
+ onCompleted: data => {
+ if (!data?.appDeactivate?.errors?.length) {
+ notify({
+ status: "success",
+ text: intl.formatMessage(messages.appDeactivated)
+ });
+ refetch();
+ closeModal();
}
}
});
@@ -150,30 +171,18 @@ export const AppsList: React.FC = ({ params }) => {
AppListUrlQueryParams
>(navigate, appsListUrl, params);
- const onAppRemove = (data: AppDeleteMutation) => {
- const errors = data.appDelete.errors;
- if (errors.length === 0) {
- if (data.appDelete.app.type === AppTypeEnum.LOCAL) {
- customAppsRefetch();
- } else {
- refetch();
- }
- closeModal();
- refetchExtensionList();
- removeAppNotify();
- } else {
- errors.forEach(error =>
- notify({
- status: "error",
- text: getAppErrorMessage(error, intl)
- })
- );
- }
- };
-
const [deleteApp, deleteAppOpts] = useAppDeleteMutation({
onCompleted: data => {
- onAppRemove(data);
+ if (!data?.appDelete?.errors?.length) {
+ if (data.appDelete.app.type === AppTypeEnum.LOCAL) {
+ customAppsRefetch();
+ } else {
+ refetch();
+ }
+ closeModal();
+ refetchExtensionList();
+ removeAppNotify();
+ }
}
});
const [
@@ -181,7 +190,11 @@ export const AppsList: React.FC = ({ params }) => {
deleteInProgressAppOpts
] = useAppDeleteFailedInstallationMutation({
onCompleted: data => {
- onAppInProgressRemove(data);
+ if (!data?.appDeleteFailedInstallation?.errors?.length) {
+ removeAppNotify();
+ appsInProgressRefetch();
+ closeModal();
+ }
}
});
@@ -256,77 +269,92 @@ export const AppsList: React.FC = ({ params }) => {
});
};
- const onAppInProgressRemove = (data: AppDeleteFailedInstallationMutation) => {
- const errors = data.appDeleteFailedInstallation.errors;
- if (errors.length === 0) {
- removeAppNotify();
- appsInProgressRefetch();
- closeModal();
- } else {
- errors.forEach(error =>
- notify({
- status: "error",
- text: getAppErrorMessage(error, intl)
- })
- );
- }
- };
+ const handleActivateAppConfirm = () =>
+ activateApp({ variables: { id: params.id } });
+
+ const handleDeactivateAppConfirm = () =>
+ deactivateApp({ variables: { id: params.id } });
+
const onAppInstallRetry = (id: string) =>
retryInstallApp({ variables: { id } });
const installedApps = data?.apps?.edges;
const customApps = customAppsData?.apps?.edges;
+ const context: AppListContextValues = React.useMemo(
+ () => ({
+ activateApp: id => openModal("app-activate", { id }),
+ deactivateApp: id => openModal("app-deactivate", { id })
+ }),
+ [activateApp, deactivateApp]
+ );
+
return (
-
-
-
- customAppUrl(id)}
- onInstalledAppRemove={id =>
- openModal("remove-app", {
- id
- })
- }
- onCustomAppRemove={id =>
- openModal("remove-custom-app", {
- id
- })
- }
- onAppInProgressRemove={id =>
- openModal("remove", {
- id
- })
- }
- />
-
+
+
+
+
+
+
+ customAppUrl(id)}
+ onInstalledAppRemove={id =>
+ openModal("remove-app", {
+ id
+ })
+ }
+ onCustomAppRemove={id =>
+ openModal("remove-custom-app", {
+ id
+ })
+ }
+ onAppInProgressRemove={id =>
+ openModal("remove", {
+ id
+ })
+ }
+ />
+
+
);
};
diff --git a/src/apps/views/AppsList/messages.ts b/src/apps/views/AppsList/messages.ts
index 914a46b28..7381db603 100644
--- a/src/apps/views/AppsList/messages.ts
+++ b/src/apps/views/AppsList/messages.ts
@@ -20,5 +20,15 @@ export const messages = defineMessages({
id: "5t/4um",
defaultMessage: "Couldn’t Install {name}",
description: "message title"
+ },
+ appActivated: {
+ id: "D/+84n",
+ defaultMessage: "App activated",
+ description: "snackbar text"
+ },
+ appDeactivated: {
+ id: "USO8PB",
+ defaultMessage: "App deactivated",
+ description: "snackbar text"
}
});
diff --git a/src/config.ts b/src/config.ts
index 416a229c5..876dfcfbe 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -54,7 +54,7 @@ export interface AppListViewSettings {
export const defaultListSettings: AppListViewSettings = {
[ListViews.APPS_LIST]: {
- rowNumber: 10
+ rowNumber: 100
},
[ListViews.ATTRIBUTE_VALUE_LIST]: {
rowNumber: 10
diff --git a/src/fragments/apps.ts b/src/fragments/apps.ts
index a686abab2..10aecf94b 100644
--- a/src/fragments/apps.ts
+++ b/src/fragments/apps.ts
@@ -31,3 +31,23 @@ export const appFragment = gql`
}
}
`;
+
+export const appListItemFragment = gql`
+ fragment AppListItem on App {
+ id
+ name
+ isActive
+ type
+ appUrl
+ permissions {
+ ...AppPermission
+ }
+ }
+`;
+
+export const appPermissionFragment = gql`
+ fragment AppPermission on Permission {
+ name
+ code
+ }
+`;
diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts
index ad1f42ab7..354f9dde9 100644
--- a/src/graphql/hooks.generated.ts
+++ b/src/graphql/hooks.generated.ts
@@ -47,6 +47,24 @@ export const AppFragmentDoc = gql`
}
}
${WebhookFragmentDoc}`;
+export const AppPermissionFragmentDoc = gql`
+ fragment AppPermission on Permission {
+ name
+ code
+}
+ `;
+export const AppListItemFragmentDoc = gql`
+ fragment AppListItem on App {
+ id
+ name
+ isActive
+ type
+ appUrl
+ permissions {
+ ...AppPermission
+ }
+}
+ ${AppPermissionFragmentDoc}`;
export const AttributeFragmentDoc = gql`
fragment Attribute on Attribute {
id
@@ -3135,16 +3153,12 @@ export const AppsListDocument = gql`
totalCount
edges {
node {
- id
- name
- isActive
- type
- appUrl
+ ...AppListItem
}
}
}
}
- `;
+ ${AppListItemFragmentDoc}`;
/**
* __useAppsListQuery__
diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts
index dbee74a96..b032fbdaf 100644
--- a/src/graphql/types.generated.ts
+++ b/src/graphql/types.generated.ts
@@ -5251,7 +5251,7 @@ export type AppsListQueryVariables = Exact<{
}>;
-export type AppsListQuery = { __typename: 'Query', apps: { __typename: 'AppCountableConnection', totalCount: number | null, pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null, endCursor: string | null }, edges: Array<{ __typename: 'AppCountableEdge', node: { __typename: 'App', id: string, name: string | null, isActive: boolean | null, type: AppTypeEnum | null, appUrl: string | null } }> } | null };
+export type AppsListQuery = { __typename: 'Query', apps: { __typename: 'AppCountableConnection', totalCount: number | null, pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null, endCursor: string | null }, edges: Array<{ __typename: 'AppCountableEdge', node: { __typename: 'App', id: string, name: string | null, isActive: boolean | null, type: AppTypeEnum | null, appUrl: string | null, permissions: Array<{ __typename: 'Permission', name: string, code: PermissionEnum }> | null } }> } | null };
export type AppsInstallationsQueryVariables = Exact<{ [key: string]: never; }>;
@@ -5909,6 +5909,10 @@ export type AddressFragment = { __typename: 'Address', city: string, cityArea: s
export type AppFragment = { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null };
+export type AppListItemFragment = { __typename: 'App', id: string, name: string | null, isActive: boolean | null, type: AppTypeEnum | null, appUrl: string | null, permissions: Array<{ __typename: 'Permission', name: string, code: PermissionEnum }> | null };
+
+export type AppPermissionFragment = { __typename: 'Permission', name: string, code: PermissionEnum };
+
export type AttributeValueFragment = { __typename: 'AttributeValue', id: string, name: string | null, slug: string | null, reference: string | null, boolean: boolean | null, date: any | null, dateTime: any | null, value: string | null, file: { __typename: 'File', url: string, contentType: string | null } | null };
export type AttributeValueDetailsFragment = { __typename: 'AttributeValue', richText: any | null, id: string, name: string | null, slug: string | null, reference: string | null, boolean: boolean | null, date: any | null, dateTime: any | null, value: string | null, file: { __typename: 'File', url: string, contentType: string | null } | null };
diff --git a/src/intl.ts b/src/intl.ts
index 63dd0c352..2c352681a 100644
--- a/src/intl.ts
+++ b/src/intl.ts
@@ -19,8 +19,8 @@ export const commonMessages = defineMessages({
defaultMessage: "Channel"
},
customApps: {
- id: "w4R/SO",
- defaultMessage: "Local Apps"
+ id: "+iV0gu",
+ defaultMessage: "Internal Apps"
},
dashboard: {
id: "hzSNj4",
diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap
index 09573833c..72ba092b5 100644
--- a/src/storybook/__snapshots__/Stories.test.ts.snap
+++ b/src/storybook/__snapshots__/Stories.test.ts.snap
@@ -25221,6 +25221,327 @@ exports[`Storyshots Views / Apps / Apps list default 1`] = `
/>
+
+
+
+
+
+
+
+
+
+
+ app custom
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -25264,17 +25585,42 @@ exports[`Storyshots Views / Apps / Apps list default 1`] = `
- There was a problem during installation
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
- app
-
-
-
-
-
- About
-
-
-
-
-
-
-
-
-
-
-
-
- app1
-
-
-
-
-
- http://localhost:3000
-
-
-
- About
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- app custom
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Marketplace is coming soon
-
-
-
-
`;
@@ -25783,7 +25766,7 @@ exports[`Storyshots Views / Apps / Apps list loading 1`] = `
@@ -25793,79 +25776,6 @@ exports[`Storyshots Views / Apps / Apps list loading 1`] = `
-
@@ -25903,7 +25813,7 @@ exports[`Storyshots Views / Apps / Apps list loading 1`] = `
-
-
-
-
-
-
- Marketplace is coming soon
-
-
-
-
`;
@@ -26028,7 +25907,7 @@ exports[`Storyshots Views / Apps / Apps list no data 1`] = `
@@ -26038,79 +25917,6 @@ exports[`Storyshots Views / Apps / Apps list no data 1`] = `
-
@@ -26146,7 +25952,7 @@ exports[`Storyshots Views / Apps / Apps list no data 1`] = `
-
-
-
-
-
-
- Marketplace is coming soon
-
-
-
-
`;