Skip to content

Commit

Permalink
can connect to mattermost. need to set up cors with fixed client origin
Browse files Browse the repository at this point in the history
  • Loading branch information
mickmister committed Jun 24, 2024
1 parent e36b2ab commit a5cb699
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ yarn-error.log*
_ignore

.parcel-cache
mm-logs
41 changes: 41 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
version: "3.9"
networks:
default:
name: "mattermost-apps-dev"
services:
mattermost:
image: "mattermost/mattermost-enterprise-edition:7.9.0" # https://hub.docker.com/r/mattermost/mattermost-enterprise-edition/tags
restart: "unless-stopped"
depends_on:
- "db"
ports:
- "8065:8065"
# env_file:
# - ".docker.env"
environment:
MM_SQLSETTINGS_DRIVERNAME: "postgres"
MM_SQLSETTINGS_DATASOURCE: "postgres://mmuser:mostest@db/mattermost_test?sslmode=disable\u0026connect_timeout=10"
MM_SERVICESETTINGS_CORSALLOWCREDENTIALS: true
MM_SERVICESETTINGS_CORSEXPOSEDHEADERS: "Access-Control-Allow-Origin,Access-Control-Allow-Methods"
MM_SERVICESETTINGS_LISTENADDRESS: ":8065"
MM_SERVICESETTINGS_SITEURL: "http://mattermost:8065"
MM_SERVICESETTINGS_ENABLEBOTACCOUNTCREATION: "true"
MM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS: "true"
MM_SERVICESETTINGS_ENABLEOAUTHSERVICEPROVIDER: "true"
MM_SERVICESETTINGS_ENABLEDEVELOPER: "true"
MM_SERVICESETTINGS_ENABLETESTING: "true"
MM_PLUGINSETTINGS_AUTOMATICPREPACKAGEDPLUGINS: "true"
MM_EXPERIMENTALSETTINGS_ENABLEAPPBAR: "true"
MM_PLUGINSETTINGS_ENABLEUPLOADS: "true"
MM_LOGSETTINGS_CONSOLELEVEL: "DEBUG"
MM_LOGSETTINGS_FILELEVEL: "DEBUG"
MM_FILESETTINGS_MAXFILESIZE: 123524266
volumes:
- "./mm-logs:/mattermost/logs:rw"
db:
image: "postgres"
restart: "unless-stopped"
environment:
POSTGRES_PASSWORD: "mostest"
POSTGRES_USER: "mmuser"
POSTGRES_DB: "mattermost_test"
33 changes: 32 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@mattermost/client": "^9.8.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand All @@ -21,6 +22,13 @@
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@mattermost/types": "^9.8.0",
"jest-environment-jsdom": "^29.7.0",
"parcel": "^2.12.0",
"process": "^0.11.10",
"ts-jest": "^29.1.5"
},
"scripts": {
"start": "parcel src/index.html --dist-dir build",
"build": "parcel build src/index.html --dist-dir build",
Expand All @@ -29,7 +37,8 @@
"lint": "eslint src/**/*.ts src/**/*.tsx",
"fix": "npm run lint -- --fix",
"check-types": "tsc --noEmit",
"ci": "npm run lint && npm run check-types && npm run test:ci && npm run build"
"ci": "npm run lint && npm run check-types && npm run test:ci && npm run build",
"mattermost": "cd docker && docker-compose up"
},
"browserslist": {
"production": [
Expand All @@ -42,11 +51,5 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"jest-environment-jsdom": "^29.7.0",
"parcel": "^2.12.0",
"process": "^0.11.10",
"ts-jest": "^29.1.5"
}
}
13 changes: 8 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SectionPage from './components/SectionPage';
import {IClient} from './client/IClient';
import {ClientProvider} from './hooks/useClient';
import {useMount} from './hooks/useMount';
import {MattermostProvider} from './hooks/useMattermost';

type AppProps = {
projectId: string;
Expand Down Expand Up @@ -58,11 +59,13 @@ const App: React.FC<AppProps> = ({projectId, sectionId, client}) => {
);

return (
<ClientProvider client={client}>
<GlobalStoreProvider initialProjectData={initialProjectData}>
{pageContent}
</GlobalStoreProvider>
</ClientProvider>
<MattermostProvider>
<ClientProvider client={client}>
<GlobalStoreProvider initialProjectData={initialProjectData}>
{pageContent}
</GlobalStoreProvider>
</ClientProvider>
</MattermostProvider>
);
}

Expand Down
89 changes: 89 additions & 0 deletions src/components/MattermostConfigButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {useGlobalStore} from '@/hooks/useGlobalStore';
import {makeClient4FromConfig, useMattermost} from '@/hooks/useMattermost';
import {useState} from 'react';

export const MattermostConfigButton = () => {
const [showForm, setShowForm] = useState(false);

const onSubmit = () => {

}

const button = (
<button
onClick={() => {
setShowForm(!showForm)}
}
>
Configure Mattermost
</button>
);

if (!showForm) {
return button;
}

return (
<>
{button}
<MattermostConfigForm
onSubmit={onSubmit}
/>
</>
);
}

type MattermostConfigFormProps = {
onSubmit: () => void;
}

const MattermostConfigForm = (props: MattermostConfigFormProps) => {
const mm = useMattermost();

const [url, setUrl] = useState(mm.savedConfig?.url || '');
const [token, setToken] = useState(mm.savedConfig?.token || '');

const onSubmit = () => {
alert('submitting');
props.onSubmit();
};

const testConnection = () => {
const client4 = makeClient4FromConfig({url, token});
client4.getMe().then((me) => {
alert(`Success! Logged in as ${me.username}`);
}, (err) => {
alert(`Error: ${err.message}`);
});
};

return (
<div>
<input
type='text'
placeholder='URL'
value={url}
onChange={(e) => setUrl(e.target.value)}
/>
<input
type='text'
placeholder='Token'
value={token}
onChange={(e) => setToken(e.target.value)}
/>
<button
type='button'
onClick={onSubmit}
>
Submit
</button>
<button
type='button'
onClick={testConnection}
>
Test Connection
</button>
</div>
)

};
2 changes: 2 additions & 0 deletions src/components/SectionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {Comments} from './Comments';
import {CreateComment} from './CreateComment';
import {SectionTitle} from './SectionTitle';
import {useGlobalStore} from '@/hooks/useGlobalStore';
import {MattermostConfigButton} from './MattermostConfigButton';

type SectionPageProps = {
projectId: string;
Expand All @@ -28,6 +29,7 @@ const SectionPage: React.FC<SectionPageProps> = ({projectId, sectionId}) => {
<Files files={files} />
<Comments entityPointer={sectionPointer} />
<CreateComment entityPointer={sectionPointer} />
<MattermostConfigButton/>
</div>
);
}
Expand Down
70 changes: 70 additions & 0 deletions src/hooks/useMattermost.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {createContext, useContext, useEffect, useMemo, useState} from 'react';
import {Client4} from '@mattermost/client';
import {MattermostConfig} from '@/types/mattermost_types';

type MattermostContextValue = {
client4: Client4 | null;
savedConfig: MattermostConfig | null;
setSavedConfig: (config: MattermostConfig) => void;
};

const mmContext = createContext<Client4 | null>(null);

export const useMattermost = (): MattermostContextValue => {
return useContext(mmContext)!;
};

export const MattermostProvider = (props: React.PropsWithChildren) => {
const [savedConfig, setSavedConfig] = useState<MattermostConfig | null>(null);
const [client4, setClient4] = useState<Client4 | null>(null);

useEffect(() => {
const config = getMattermostConfigFromLocalStorage();
if (!config) {
return;
}

const client = makeClient4FromConfig(config);
setClient4(client);
setSavedConfig(config);
}, []);

const value = useMemo(() => ({
client4,
savedConfig,
setSavedConfig: (config: MattermostConfig) => {
const client = makeClient4FromConfig(config);
setClient4(client);
setSavedConfig(config);
},
}), [savedConfig, client4]);

return (
<mmContext.Provider value={value}>
{props.children}
</mmContext.Provider>
);
};

const MATTERMOST_CONFIG_LOCAL_STORAGE_KEY = 'mattermost_config';

const getMattermostConfigFromLocalStorage = (): MattermostConfig | null => {
const configString = localStorage.getItem(MATTERMOST_CONFIG_LOCAL_STORAGE_KEY);
if (!configString) {
return null;
}

return JSON.parse(configString);
};

const setMattermostConfig = (config: MattermostConfig) => {
const configString = JSON.stringify(config);
localStorage.setItem(MATTERMOST_CONFIG_LOCAL_STORAGE_KEY, configString);
}

export const makeClient4FromConfig = (config: MattermostConfig): Client4 => {
const client4 = new Client4();
client4.setUrl(config.url);
client4.setToken(config.token);
return client4;
};
4 changes: 4 additions & 0 deletions src/types/mattermost_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type MattermostConfig = {
url: string;
token: string;
}

0 comments on commit a5cb699

Please sign in to comment.