Skip to content

Commit 2e7f9a4

Browse files
SaraVieiraCompuIves
authored andcommitted
add frozen atribute to sandboxes (codesandbox#1107)
* add frozen atribute to sandboxes * add to contribs * make swtich small
1 parent bcd8383 commit 2e7f9a4

File tree

12 files changed

+1637
-33
lines changed

12 files changed

+1637
-33
lines changed

.all-contributorsrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,15 @@
605605
"doc"
606606
]
607607
},
608+
{
609+
"login": "SaraVieira",
610+
"name": "Sara Vieira",
611+
"avatar_url": "https://avatars0.githubusercontent.com/u/1051509?v=4",
612+
"profile": "http://iamsaravieira.com",
613+
"contributions": [
614+
"code",
615+
"ideas"
616+
},
608617
{
609618
"login": "melanieseltzer",
610619
"name": "Melanie Seltzer",

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ sandboxes.
2424
CodeSandbox consists of several separate servers, some of which are open
2525
sourced.
2626

27-
* Client: the web application
28-
* Server: the [Phoenix](https://github.com/phoenixframework/phoenix) API server
29-
* Nginx: Nginx config files
30-
* [Git Extractor](https://github.com/CompuIves/codesandbox-git-extractor):
27+
- Client: the web application
28+
- Server: the [Phoenix](https://github.com/phoenixframework/phoenix) API server
29+
- Nginx: Nginx config files
30+
- [Git Extractor](https://github.com/CompuIves/codesandbox-git-extractor):
3131
responsible for extracting the source from a GitHub repository
32-
* [CLI](https://github.com/CompuIves/codesandbox-cli): the CLI to upload a
32+
- [CLI](https://github.com/CompuIves/codesandbox-cli): the CLI to upload a
3333
CodeSandbox project from your command line
3434

3535
## Contributors
@@ -50,4 +50,5 @@ Thanks goes to these wonderful people
5050
| [<img src="https://avatars0.githubusercontent.com/u/1195863?v=4" width="100px;"/><br /><sub><b>Joe Ng'ethe</b></sub>](http://joey.co.ke)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=joeynimu "Code") | [<img src="https://avatars0.githubusercontent.com/u/576935?v=4" width="100px;"/><br /><sub><b>Carles Codony</b></sub>](https://github.com/bitblitter)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=bitblitter "Code") | [<img src="https://avatars2.githubusercontent.com/u/468006?v=4" width="100px;"/><br /><sub><b>Vytenis</b></sub>](https://github.com/FDiskas)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=FDiskas "Code") | [<img src="https://avatars1.githubusercontent.com/u/894149?v=4" width="100px;"/><br /><sub><b>Manuel Dugué</b></sub>](http://manueldugue.de)<br />[🐛](https://github.com/CompuIves/codesandbox-client/issues?q=author%3Amdugue "Bug reports") [💻](https://github.com/CompuIves/codesandbox-client/commits?author=mdugue "Code") | [<img src="https://avatars2.githubusercontent.com/u/5346497?v=4" width="100px;"/><br /><sub><b>Demian Dekoninck</b></sub>](https://dem.be)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=DemianD "Code") | [<img src="https://avatars2.githubusercontent.com/u/3144549?v=4" width="100px;"/><br /><sub><b>Drake Costa</b></sub>](http://www.saeris.io)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=Saeris "Code") | [<img src="https://avatars2.githubusercontent.com/u/433394?v=4" width="100px;"/><br /><sub><b>Marko Stijak</b></sub>](https://cxjs.io/)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=mstijak "Code") |
5151
| [<img src="https://avatars2.githubusercontent.com/u/10588170?v=4" width="100px;"/><br /><sub><b>Ilya</b></sub>](https://twitter.com/ilya_komar0ff)<br />[💬](#question-Komar0ff "Answering Questions") [🤔](#ideas-Komar0ff "Ideas, Planning, & Feedback") | [<img src="https://avatars2.githubusercontent.com/u/10627086?v=4" width="100px;"/><br /><sub><b>Emerson Laurentino</b></sub>](https://twitter.com/elaurent_)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=emersonlaurentino "Code") [🐛](https://github.com/CompuIves/codesandbox-client/issues?q=author%3Aemersonlaurentino "Bug reports") | [<img src="https://avatars3.githubusercontent.com/u/180963?v=4" width="100px;"/><br /><sub><b>Aaron Reisman</b></sub>](https://github.com/lifeiscontent)<br />[🐛](https://github.com/CompuIves/codesandbox-client/issues?q=author%3Alifeiscontent "Bug reports") [💻](https://github.com/CompuIves/codesandbox-client/commits?author=lifeiscontent "Code") [📦](#platform-lifeiscontent "Packaging/porting to new platform") | [<img src="https://avatars2.githubusercontent.com/u/19484365?v=4" width="100px;"/><br /><sub><b>Colton Colcleasure</b></sub>](https://github.com/colshacol)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=colshacol "Code") [🐛](https://github.com/CompuIves/codesandbox-client/issues?q=author%3Acolshacol "Bug reports") | [<img src="https://avatars0.githubusercontent.com/u/497242?v=4" width="100px;"/><br /><sub><b>PJ Walker</b></sub>](https://github.com/PJWalker)<br />[🐛](https://github.com/CompuIves/codesandbox-client/issues?q=author%3APJWalker "Bug reports") [💻](https://github.com/CompuIves/codesandbox-client/commits?author=PJWalker "Code") | [<img src="https://avatars2.githubusercontent.com/u/29819102?v=4" width="100px;"/><br /><sub><b>Satya Rohith</b></sub>](https://satya.tech)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=satyarohith "Code") [📖](https://github.com/CompuIves/codesandbox-client/commits?author=satyarohith "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/17421347?v=4" width="100px;"/><br /><sub><b>Melanie Seltzer</b></sub>](https://www.melanieseltzer.io/)<br />[💻](https://github.com/CompuIves/codesandbox-client/commits?author=melanieseltzer "Code") |
5252
| [<img src="https://avatars1.githubusercontent.com/u/23313266?v=4" width="100px;"/><br /><sub><b>ZYSzys</b></sub>](http://zyszys.top)<br />[📖](https://github.com/CompuIves/codesandbox-client/commits?author=ZYSzys "Documentation") |
53+
5354
<!-- ALL-CONTRIBUTORS-LIST:END -->

packages/app/src/app/pages/Sandbox/Editor/Workspace/Project/elements.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import styled from 'styled-components';
1+
import styled, { css } from 'styled-components';
2+
import Question from 'react-icons/lib/go/question';
23
import EditPenIcon from 'react-icons/lib/md/create';
34

45
import { Link } from 'react-router-dom';
@@ -34,6 +35,11 @@ export const PrivacyContainer = styled.span`
3435
margin-bottom: 1rem;
3536
`;
3637

38+
export const FreezeConatainer = styled.span`
39+
display: flex;
40+
justify-content: flex-end;
41+
`;
42+
3743
export const Title = styled.div`
3844
font-size: 1rem;
3945
font-weight: 400;
@@ -81,3 +87,10 @@ export const EditPen = styled(EditPenIcon)`
8187
color: ${props => (props.theme.light ? '#636363' : 'white')};
8288
}
8389
`;
90+
91+
const iconStyles = css`
92+
opacity: 0.5;
93+
margin-left: 0.5em;
94+
`;
95+
96+
export const Icon = styled(Question)(iconStyles);

packages/app/src/app/pages/Sandbox/Editor/Workspace/Project/index.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import PrivacyStatus from 'app/components/PrivacyStatus';
1515
import GithubBadge from 'app/components/GithubBadge';
1616
import createEditableTags from 'app/components/EditableTags';
1717
import Tags from 'app/components/Tags';
18+
import Switch from 'common/components/Switch';
1819
import Tooltip from 'common/components/Tooltip';
1920

2021
import getTemplateDefinition from 'common/templates';
@@ -30,6 +31,8 @@ import {
3031
EditPen,
3132
PropertyValue,
3233
PropertyName,
34+
Icon,
35+
FreezeConatainer,
3336
} from './elements';
3437

3538
class Project extends React.Component {
@@ -67,6 +70,13 @@ class Project extends React.Component {
6770
}
6871
};
6972

73+
updateFrozenState = () => {
74+
const frozen = !this.props.store.editor.currentSandbox.isFrozen;
75+
this.props.signals.editor.frozenUpdated({
76+
frozen,
77+
});
78+
};
79+
7080
updateSandboxInfo = () => {
7181
this.props.signals.workspace.sandboxInfoUpdated();
7282
this.setState({
@@ -93,7 +103,6 @@ class Project extends React.Component {
93103
const template = getTemplateDefinition(sandbox.template);
94104

95105
const EditableTags = createEditableTags(template.color);
96-
97106
return (
98107
<div style={{ marginBottom: '1rem' }}>
99108
<Item style={{ marginTop: '.5rem' }}>
@@ -257,6 +266,25 @@ class Project extends React.Component {
257266
</a>
258267
</PropertyValue>
259268
</Item>
269+
{sandbox.owned ? (
270+
<Item flex>
271+
<PropertyName>
272+
Frozen
273+
<Tooltip title="When true this sandbox will fork on edit">
274+
<Icon />
275+
</Tooltip>
276+
</PropertyName>
277+
<PropertyValue>
278+
<FreezeConatainer>
279+
<Switch
280+
small
281+
right={sandbox.isFrozen}
282+
onClick={this.updateFrozenState}
283+
/>
284+
</FreezeConatainer>
285+
</PropertyValue>
286+
</Item>
287+
) : null}
260288
</div>
261289
);
262290
}

packages/app/src/app/store/modules/editor/actions.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,30 @@ export function setCurrentModuleByTab({ state, props }) {
118118
}
119119
}
120120

121+
export function updatePrivacy({ api, props, state }) {
122+
const id = state.get('editor.currentId');
123+
124+
return api
125+
.patch(`/sandboxes/${id}/privacy`, {
126+
sandbox: {
127+
privacy: props.privacy,
128+
},
129+
})
130+
.then(() => undefined);
131+
}
132+
133+
export function updateFrozen({ api, props, state }) {
134+
const id = state.get('editor.currentId');
135+
136+
return api
137+
.put(`/sandboxes/${id}`, {
138+
sandbox: {
139+
is_frozen: props.frozen,
140+
},
141+
})
142+
.then(() => state.set('editor.currentSandbox.isFrozen', props.frozen));
143+
}
144+
121145
export function forceRender({ state }) {
122146
state.set('editor.forceRender', state.get('editor.forceRender') + 1);
123147
}

packages/app/src/app/store/modules/editor/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export default Module({
8484
errorsCleared: sequences.clearErrors,
8585
projectViewToggled: sequences.toggleProjectView,
8686
previewActionReceived: sequences.handlePreviewAction,
87+
privacyUpdated: sequences.updatePrivacy,
88+
frozenUpdated: sequences.updateFrozen,
8789
quickActionsOpened: sequences.openQuickActions,
8890
quickActionsClosed: sequences.closeQuickActions,
8991
setPreviewBounds: sequences.setPreviewBounds,

packages/app/src/app/store/modules/editor/model.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const Sandbox = types.model({
8484
originalGit: types.maybeNull(Git),
8585
originalGitCommitSha: types.maybeNull(types.string),
8686
owned: types.boolean,
87+
isFrozen: types.boolean,
8788
privacy: types.number,
8889
sourceId: types.string,
8990
tags: types.array(types.string),

packages/app/src/app/store/modules/editor/sequences.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
unSetReceivingStatus,
1414
} from '../live/actions';
1515
import {
16-
ensureOwnedSandbox,
16+
ensureOwnedEditable,
1717
forkSandbox,
1818
fetchGitChanges,
1919
closeModal,
@@ -78,6 +78,20 @@ export const changeCurrentTab = [set(state`editor.currentTabId`, props`tabId`)];
7878

7979
export const unsetDirtyTab = actions.unsetDirtyTab;
8080

81+
export const updatePrivacy = [
82+
actions.ensureValidPrivacy,
83+
{
84+
valid: [
85+
set(state`editor.isUpdatingPrivacy`, true),
86+
actions.updatePrivacy,
87+
set(state`editor.isUpdatingPrivacy`, false),
88+
],
89+
invalid: [],
90+
},
91+
];
92+
93+
export const updateFrozen = actions.updateFrozen;
94+
8195
export const toggleLikeSandbox = [
8296
when(state`editor.sandboxes.${props`id`}.userLiked`),
8397
{
@@ -132,7 +146,7 @@ export const changeCode = [
132146

133147
export const saveChangedModules = [
134148
track('Save Modified Modules', {}),
135-
ensureOwnedSandbox,
149+
ensureOwnedEditable,
136150
actions.outputChangedModules,
137151
actions.saveChangedModules,
138152
actions.removeChangedModules,
@@ -164,7 +178,7 @@ export const prettifyCode = [
164178

165179
export const saveCode = [
166180
track('Save Code', {}),
167-
ensureOwnedSandbox,
181+
ensureOwnedEditable,
168182
when(state`preferences.settings.prettifyOnSaveEnabled`),
169183
{
170184
true: [prettifyCode],
@@ -201,7 +215,7 @@ export const discardModuleChanges = [
201215
export const addNpmDependency = [
202216
track('Add NPM Dependency', {}),
203217
closeModal,
204-
ensureOwnedSandbox,
218+
ensureOwnedEditable,
205219
when(props`version`),
206220
{
207221
true: [],
@@ -214,7 +228,7 @@ export const addNpmDependency = [
214228

215229
export const removeNpmDependency = [
216230
track('Remove NPM Dependency', {}),
217-
ensureOwnedSandbox,
231+
ensureOwnedEditable,
218232
actions.removeNpmDependencyFromPackage,
219233
changeCode,
220234
saveCode,

packages/app/src/app/store/modules/files/sequences.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { push, set, concat } from 'cerebral/operators';
22
import { state, props } from 'cerebral/tags';
3-
import { ensureOwnedSandbox, closeModal } from '../../sequences';
3+
import { ensureOwnedEditable, closeModal } from '../../sequences';
44
import { setCurrentModule, addNotification } from '../../factories';
55
import { closeTabByIndex, setModal } from '../../actions';
66
import {
@@ -31,7 +31,7 @@ export const getUploadedFiles = [
3131
];
3232

3333
export const removeModule = [
34-
ensureOwnedSandbox,
34+
ensureOwnedEditable,
3535
actions.whenModuleIsSelected,
3636
{
3737
true: setCurrentModule(state`editor.mainModule.id`),
@@ -46,7 +46,7 @@ export const removeModule = [
4646
];
4747

4848
export const massCreateModules = [
49-
ensureOwnedSandbox,
49+
ensureOwnedEditable,
5050
actions.massCreateModules,
5151
{
5252
success: [
@@ -67,7 +67,7 @@ export const deleteUploadedFile = [
6767
];
6868

6969
export const createModule = [
70-
ensureOwnedSandbox,
70+
ensureOwnedEditable,
7171
actions.createOptimisticModule,
7272
push(
7373
state`editor.sandboxes.${state`editor.currentId`}.modules`,
@@ -112,7 +112,7 @@ export const uploadFiles = [
112112
];
113113

114114
export const renameModule = [
115-
ensureOwnedSandbox,
115+
ensureOwnedEditable,
116116
actions.renameModule,
117117
actions.saveNewModuleName,
118118
{
@@ -125,7 +125,7 @@ export const renameModule = [
125125
];
126126

127127
export const renameDirectory = [
128-
ensureOwnedSandbox,
128+
ensureOwnedEditable,
129129
actions.renameDirectory,
130130
actions.saveNewDirectoryName,
131131
{
@@ -138,7 +138,7 @@ export const renameDirectory = [
138138
];
139139

140140
export const createDirectory = [
141-
ensureOwnedSandbox,
141+
ensureOwnedEditable,
142142
actions.createOptimisticDirectory,
143143
push(
144144
state`editor.sandboxes.${state`editor.currentId`}.directories`,
@@ -164,7 +164,7 @@ export const removeDirectory = [
164164
];
165165

166166
export const deleteDirectory = [
167-
ensureOwnedSandbox,
167+
ensureOwnedEditable,
168168
removeDirectory,
169169
actions.deleteDirectory,
170170
{
@@ -180,7 +180,7 @@ export const deleteDirectory = [
180180
];
181181

182182
export const moveDirectoryToDirectory = [
183-
ensureOwnedSandbox,
183+
ensureOwnedEditable,
184184
actions.moveDirectoryToDirectory,
185185
actions.saveNewDirectoryDirectoryShortid,
186186
{
@@ -196,7 +196,7 @@ export const moveDirectoryToDirectory = [
196196
];
197197

198198
export const moveModuleToDirectory = [
199-
ensureOwnedSandbox,
199+
ensureOwnedEditable,
200200
actions.moveModuleToDirectory,
201201
actions.saveNewModuleDirectoryShortid,
202202
{

packages/app/src/app/store/modules/workspace/sequences.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { state, props } from 'cerebral/tags';
33
import getTemplate from 'common/templates';
44
import * as actions from './actions';
55
import {
6-
ensureOwnedSandbox,
6+
ensureOwnedEditable,
77
loadSandbox,
88
closeModal,
99
openModal,
@@ -54,7 +54,7 @@ export const changeValue = [
5454
];
5555

5656
export const updateSandboxInfo = [
57-
ensureOwnedSandbox,
57+
ensureOwnedEditable,
5858
set(
5959
state`editor.sandboxes.${state`editor.currentId`}.title`,
6060
state`workspace.project.title`
@@ -68,7 +68,7 @@ export const updateSandboxInfo = [
6868
];
6969

7070
export const addExternalResource = [
71-
ensureOwnedSandbox,
71+
ensureOwnedEditable,
7272
push(
7373
state`editor.sandboxes.${state`editor.currentId`}.externalResources`,
7474
props`resource`
@@ -84,7 +84,7 @@ export const addExternalResource = [
8484
];
8585

8686
export const removeExternalResource = [
87-
ensureOwnedSandbox,
87+
ensureOwnedEditable,
8888
actions.removeOptimisticExternalResource,
8989
actions.removeExternalResource,
9090
{
@@ -102,7 +102,7 @@ export const removeExternalResource = [
102102
export const updateTag = [set(state`workspace.tags.tagName`, props`tagName`)];
103103

104104
export const addTag = [
105-
ensureOwnedSandbox,
105+
ensureOwnedEditable,
106106
push(
107107
state`editor.sandboxes.${state`editor.currentId`}.tags`,
108108
state`workspace.tags.tagName`
@@ -119,7 +119,7 @@ export const addTag = [
119119
];
120120

121121
export const removeTag = [
122-
ensureOwnedSandbox,
122+
ensureOwnedEditable,
123123
actions.removeTagFromState,
124124
actions.removeTag,
125125
set(state`editor.sandboxes.${state`editor.currentId`}.tags`, props`tags`),

0 commit comments

Comments
 (0)