linked-data-browser 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/components/nav/DialogProvider.tsx +3 -2
- package/components/nav/Layout.tsx +7 -0
- package/components/nav/header/AvatarMenu.tsx +81 -57
- package/infra/ansible.cfg +0 -0
- package/infra/hosts +2 -0
- package/infra/hosts.example +2 -0
- package/infra/nginx.conf.j2 +12 -0
- package/infra/playbook.yml +77 -0
- package/infra/secrets.yml +11 -0
- package/lib/icons/LogOut.tsx +4 -0
- package/lib/icons/User.tsx +4 -0
- package/package.json +5 -5
- package/resourceViews/RawCode/RawCodeView.tsx +6 -1
package/README.md
CHANGED
|
@@ -15,9 +15,10 @@ import {
|
|
|
15
15
|
DialogDescription,
|
|
16
16
|
DialogClose,
|
|
17
17
|
} from '../ui/dialog';
|
|
18
|
-
import {
|
|
18
|
+
import { View } from 'react-native';
|
|
19
19
|
import { Button } from '../ui/button';
|
|
20
20
|
import { Text } from '../ui/text';
|
|
21
|
+
import { Input } from '../ui/input';
|
|
21
22
|
|
|
22
23
|
type DialogOptions =
|
|
23
24
|
| { type: 'confirm'; title: string; message?: string }
|
|
@@ -112,7 +113,7 @@ export const DialogProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
112
113
|
|
|
113
114
|
{options?.type === 'prompt' && (
|
|
114
115
|
<View className="my-2">
|
|
115
|
-
<
|
|
116
|
+
<Input
|
|
116
117
|
value={inputValue}
|
|
117
118
|
onChangeText={setInputValue}
|
|
118
119
|
placeholder="Enter text..."
|
|
@@ -16,6 +16,7 @@ import { Header } from './header/Header';
|
|
|
16
16
|
import { View } from 'react-native';
|
|
17
17
|
import { useValidView, ValidViewProvider } from './useValidView';
|
|
18
18
|
import { DialogProvider } from './DialogProvider';
|
|
19
|
+
import { useSolidAuth } from '@ldo/solid-react';
|
|
19
20
|
|
|
20
21
|
export const ValidViewContext = createContext<{
|
|
21
22
|
validViews: ResourceViewConfig[];
|
|
@@ -25,6 +26,12 @@ export const ValidViewContext = createContext<{
|
|
|
25
26
|
}>({});
|
|
26
27
|
|
|
27
28
|
export const Layout: FunctionComponent = () => {
|
|
29
|
+
const { ranInitialAuthCheck } = useSolidAuth();
|
|
30
|
+
|
|
31
|
+
if (!ranInitialAuthCheck) {
|
|
32
|
+
return <></>;
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
return (
|
|
29
36
|
<DialogProvider>
|
|
30
37
|
<ValidViewProvider>
|
|
@@ -1,62 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useLdo,
|
|
3
|
+
useResource,
|
|
4
|
+
useSolidAuth,
|
|
5
|
+
useSubject,
|
|
6
|
+
} from '@ldo/solid-react';
|
|
1
7
|
import React from 'react';
|
|
2
|
-
|
|
3
8
|
import { FunctionComponent } from 'react';
|
|
4
|
-
import {
|
|
9
|
+
import { View } from 'react-native';
|
|
10
|
+
import { SolidProfileShapeShapeType } from '../../../.ldo/profile.shapeTypes';
|
|
11
|
+
import { Avatar, AvatarFallback, AvatarImage } from '../../ui/avatar';
|
|
12
|
+
import { Text } from '../../ui/text';
|
|
13
|
+
import { Button } from '../../ui/button';
|
|
14
|
+
import { ThemeToggleMenu } from './ThemeToggleMenu';
|
|
15
|
+
import {
|
|
16
|
+
DropdownMenu,
|
|
17
|
+
DropdownMenuContent,
|
|
18
|
+
DropdownMenuItem,
|
|
19
|
+
DropdownMenuSeparator,
|
|
20
|
+
DropdownMenuTrigger,
|
|
21
|
+
} from '../../ui/dropdown-menu';
|
|
22
|
+
import { User } from '../../../lib/icons/User';
|
|
23
|
+
import { LogOut } from '../../../lib/icons/LogOut';
|
|
24
|
+
import { useTargetResource } from '../../TargetResourceProvider';
|
|
5
25
|
|
|
6
26
|
export const AvatarMenu: FunctionComponent = () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// <Avatar
|
|
16
|
-
// source={{ uri: 'https://api.lorem.space/image/face?w=150&h=150' }}
|
|
17
|
-
// />
|
|
18
|
-
// </TouchableWithoutFeedback>
|
|
19
|
-
// );
|
|
20
|
-
// return (
|
|
21
|
-
// <Popover
|
|
22
|
-
// anchor={renderAvatar}
|
|
23
|
-
// visible={menuVisible}
|
|
24
|
-
// placement="bottom end"
|
|
25
|
-
// onBackdropPress={() => setMenuVisible(false)}
|
|
26
|
-
// style={styles.popover}
|
|
27
|
-
// >
|
|
28
|
-
// <Layout>
|
|
29
|
-
// <View style={styles.profileHeader}>
|
|
30
|
-
// <Avatar
|
|
31
|
-
// size="giant"
|
|
32
|
-
// source={{ uri: 'https://api.lorem.space/image/face?w=150&h=150' }}
|
|
33
|
-
// />
|
|
34
|
-
// <View style={styles.profileText}>
|
|
35
|
-
// <Text category="h6">{profile?.fn || ''}</Text>
|
|
36
|
-
// <Button size="tiny">Edit your profile</Button>
|
|
37
|
-
// </View>
|
|
38
|
-
// </View>
|
|
39
|
-
// <Divider />
|
|
40
|
-
// <ThemeToggleMenu />
|
|
41
|
-
// <Divider />
|
|
42
|
-
// <MenuItem
|
|
43
|
-
// onPress={logout}
|
|
44
|
-
// title="Log Out"
|
|
45
|
-
// accessoryLeft={(props) => <Icon {...props} name="log-out" />}
|
|
46
|
-
// />
|
|
47
|
-
// </Layout>
|
|
48
|
-
// </Popover>
|
|
49
|
-
// );
|
|
50
|
-
};
|
|
27
|
+
const { dataset } = useLdo();
|
|
28
|
+
const { session, logout } = useSolidAuth();
|
|
29
|
+
// TODO: Use WebId Resource to render a skeleton loader
|
|
30
|
+
const webIdResource = useResource(session.webId);
|
|
31
|
+
const profile = useSubject(SolidProfileShapeShapeType, session.webId);
|
|
32
|
+
const { navigateTo } = useTargetResource();
|
|
33
|
+
|
|
34
|
+
if (!session.webId) return <></>;
|
|
51
35
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
36
|
+
console.log(profile?.['@id']);
|
|
37
|
+
console.log(profile?.hasPhoto?.['@id']);
|
|
38
|
+
console.log(webIdResource?.isLoading());
|
|
39
|
+
console.log(dataset.toString());
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<DropdownMenu>
|
|
43
|
+
<DropdownMenuTrigger asChild>
|
|
44
|
+
<Button key="setMemu" variant="ghost" className="w-10">
|
|
45
|
+
<Avatar alt={profile?.fn ? `${profile.fn}'s Avatar` : ''}>
|
|
46
|
+
<AvatarImage source={{ uri: profile?.hasPhoto?.['@id'] }} />
|
|
47
|
+
<AvatarFallback>
|
|
48
|
+
<Text>
|
|
49
|
+
<User />
|
|
50
|
+
</Text>
|
|
51
|
+
</AvatarFallback>
|
|
52
|
+
</Avatar>
|
|
53
|
+
</Button>
|
|
54
|
+
</DropdownMenuTrigger>
|
|
55
|
+
<DropdownMenuContent className="w-64 native:w-72 mr-2 mt-2">
|
|
56
|
+
<View className="p-2 flex-row items-center">
|
|
57
|
+
<Avatar
|
|
58
|
+
alt={profile?.fn ? `${profile.fn}'s Avatar` : ''}
|
|
59
|
+
className="w-20 h-20"
|
|
60
|
+
>
|
|
61
|
+
<AvatarImage source={{ uri: profile?.hasPhoto?.['@id'] }} />
|
|
62
|
+
<AvatarFallback>
|
|
63
|
+
<Text>
|
|
64
|
+
<User />
|
|
65
|
+
</Text>
|
|
66
|
+
</AvatarFallback>
|
|
67
|
+
</Avatar>
|
|
68
|
+
<View className="ml-2">
|
|
69
|
+
<Text>{profile?.fn || ''}</Text>
|
|
70
|
+
<Button size="sm" onPress={() => navigateTo(session.webId ?? '')}>
|
|
71
|
+
<Text>Edit your profile</Text>
|
|
72
|
+
</Button>
|
|
73
|
+
</View>
|
|
74
|
+
</View>
|
|
75
|
+
<DropdownMenuSeparator />
|
|
76
|
+
<ThemeToggleMenu />
|
|
77
|
+
<DropdownMenuSeparator />
|
|
78
|
+
<DropdownMenuItem onPress={logout}>
|
|
79
|
+
<Text className="flex flex-row gap-1 items-center">
|
|
80
|
+
<LogOut /> Log Out
|
|
81
|
+
</Text>
|
|
82
|
+
</DropdownMenuItem>
|
|
83
|
+
</DropdownMenuContent>
|
|
84
|
+
</DropdownMenu>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
File without changes
|
package/infra/hosts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
server {
|
|
2
|
+
listen 80;
|
|
3
|
+
server_name {{ domain }};
|
|
4
|
+
location / {
|
|
5
|
+
proxy_pass http://localhost:3000;
|
|
6
|
+
proxy_http_version 1.1;
|
|
7
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
8
|
+
proxy_set_header Connection 'upgrade';
|
|
9
|
+
proxy_set_header Host $host;
|
|
10
|
+
proxy_cache_bypass $http_upgrade;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
- name: Deploy Node Git Server
|
|
2
|
+
hosts: web
|
|
3
|
+
become: yes
|
|
4
|
+
|
|
5
|
+
vars:
|
|
6
|
+
docker_image: "jaxoncreed/integration-pod:latest"
|
|
7
|
+
|
|
8
|
+
vars_files:
|
|
9
|
+
- secrets.yml
|
|
10
|
+
|
|
11
|
+
tasks:
|
|
12
|
+
- name: Install required packages
|
|
13
|
+
apt:
|
|
14
|
+
name:
|
|
15
|
+
- docker.io
|
|
16
|
+
- docker-compose
|
|
17
|
+
- nginx
|
|
18
|
+
- certbot
|
|
19
|
+
- python3-certbot-nginx
|
|
20
|
+
update_cache: yes
|
|
21
|
+
|
|
22
|
+
- name: Enable Docker service
|
|
23
|
+
systemd:
|
|
24
|
+
name: docker
|
|
25
|
+
enabled: yes
|
|
26
|
+
state: started
|
|
27
|
+
|
|
28
|
+
- name: Log in to Docker Hub
|
|
29
|
+
docker_login:
|
|
30
|
+
registry_url: https://index.docker.io/v1/
|
|
31
|
+
username: "{{ dockerhub_username }}"
|
|
32
|
+
password: "{{ dockerhub_password }}"
|
|
33
|
+
|
|
34
|
+
- name: Pull Docker image
|
|
35
|
+
docker_image:
|
|
36
|
+
name: "{{ docker_image }}"
|
|
37
|
+
source: pull
|
|
38
|
+
|
|
39
|
+
- name: Run container
|
|
40
|
+
docker_container:
|
|
41
|
+
name: server
|
|
42
|
+
image: "{{ docker_image }}"
|
|
43
|
+
state: started
|
|
44
|
+
restart_policy: always
|
|
45
|
+
ports:
|
|
46
|
+
- "3000:3000"
|
|
47
|
+
|
|
48
|
+
- name: Set up NGINX config
|
|
49
|
+
template:
|
|
50
|
+
src: nginx.conf.j2
|
|
51
|
+
dest: /etc/nginx/sites-available/server
|
|
52
|
+
notify:
|
|
53
|
+
- Reload nginx
|
|
54
|
+
|
|
55
|
+
- name: Enable site
|
|
56
|
+
file:
|
|
57
|
+
src: /etc/nginx/sites-available/server
|
|
58
|
+
dest: /etc/nginx/sites-enabled/server
|
|
59
|
+
state: link
|
|
60
|
+
force: true
|
|
61
|
+
|
|
62
|
+
- name: Remove default site
|
|
63
|
+
file:
|
|
64
|
+
path: /etc/nginx/sites-enabled/default
|
|
65
|
+
state: absent
|
|
66
|
+
|
|
67
|
+
- name: Obtain SSL cert
|
|
68
|
+
command: >
|
|
69
|
+
certbot --nginx -d {{ domain }} --non-interactive --agree-tos -m {{ email }}
|
|
70
|
+
args:
|
|
71
|
+
creates: "/etc/letsencrypt/live/{{ domain }}"
|
|
72
|
+
|
|
73
|
+
handlers:
|
|
74
|
+
- name: Reload nginx
|
|
75
|
+
service:
|
|
76
|
+
name: nginx
|
|
77
|
+
state: reloaded
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
$ANSIBLE_VAULT;1.1;AES256
|
|
2
|
+
66363662346539366434346433653035333336306162626463336363356639346663336438313331
|
|
3
|
+
3066616236343234333865626233313230396661333865300a623962646230303839643136333039
|
|
4
|
+
66323262396437616333613434303932343462366266323732633439356362373566313062313037
|
|
5
|
+
6337366430376162340a323464316363366439663531373661343339303662633239343762643234
|
|
6
|
+
32353164633332623839353562633932303162323535316665633936623638326234353035663638
|
|
7
|
+
62303032393362623438303064653336343766663737353066656131386436613539353262343562
|
|
8
|
+
61336563346561373762633839396163636530316239616561303338353135373137333235366332
|
|
9
|
+
31383865393732366165393538333839623065336161336335353334393365323965363136333231
|
|
10
|
+
62623635376134316366653630653037343133323566373335323430646362303031383036336139
|
|
11
|
+
6266383137663536623064346636626436623333613566366233
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linked-data-browser",
|
|
3
3
|
"main": "index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev:ios": "expo start -c --ios",
|
|
7
7
|
"dev:web": "concurrently \"npm run solid-server\" \"expo start -c --web\"",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"build": "npm run build:standalone && npm run build:server"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@inrupt/solid-client-authn-browser": "^
|
|
21
|
-
"@ldo/connected-solid": "^1.0.0-alpha.
|
|
22
|
-
"@ldo/ldo": "^1.0.0-alpha.
|
|
23
|
-
"@ldo/solid-react": "^1.0.0-alpha.
|
|
20
|
+
"@inrupt/solid-client-authn-browser": "^3.0.0",
|
|
21
|
+
"@ldo/connected-solid": "^1.0.0-alpha.27",
|
|
22
|
+
"@ldo/ldo": "^1.0.0-alpha.27",
|
|
23
|
+
"@ldo/solid-react": "^1.0.0-alpha.27",
|
|
24
24
|
"@monaco-editor/react": "^4.7.0",
|
|
25
25
|
"@radix-ui/react-dialog": "^1.1.14",
|
|
26
26
|
"@radix-ui/react-dropdown-menu": "^2.1.15",
|
|
@@ -16,6 +16,7 @@ export const RawCodeView: FunctionComponent = () => {
|
|
|
16
16
|
const { targetUri } = useTargetResource();
|
|
17
17
|
const { fetch } = useSolidAuth();
|
|
18
18
|
const [content, setContent] = useState<string>('');
|
|
19
|
+
const [contentType, setContentType] = useState<string>('');
|
|
19
20
|
|
|
20
21
|
// Independently fetch the target resource, so we have the raw turtle
|
|
21
22
|
const fetchContent = useCallback(async () => {
|
|
@@ -27,12 +28,16 @@ export const RawCodeView: FunctionComponent = () => {
|
|
|
27
28
|
});
|
|
28
29
|
}
|
|
29
30
|
setContent(await response.text());
|
|
31
|
+
setContentType(response.headers.get('content-type') ?? '');
|
|
30
32
|
}, [fetch, targetUri]);
|
|
31
33
|
|
|
32
34
|
const submitChanges = useCallback(async () => {
|
|
33
35
|
if (!targetUri) return;
|
|
34
36
|
const response = await fetch(targetUri, {
|
|
35
37
|
method: 'put',
|
|
38
|
+
headers: {
|
|
39
|
+
'content-type': contentType,
|
|
40
|
+
},
|
|
36
41
|
body: content,
|
|
37
42
|
});
|
|
38
43
|
if (response.status !== 205) {
|
|
@@ -44,7 +49,7 @@ export const RawCodeView: FunctionComponent = () => {
|
|
|
44
49
|
title: `Document Saved`,
|
|
45
50
|
});
|
|
46
51
|
await fetchContent();
|
|
47
|
-
}, [content, fetch, fetchContent, targetUri]);
|
|
52
|
+
}, [content, contentType, fetch, fetchContent, targetUri]);
|
|
48
53
|
|
|
49
54
|
useEffect(() => {
|
|
50
55
|
fetchContent();
|