Skip to content

Commit

Permalink
Merge pull request #307 from frappe/for-release-v1.14
Browse files Browse the repository at this point in the history
  • Loading branch information
surajshetty3416 authored Jan 29, 2025
2 parents 8fa40c6 + ed47c65 commit 8d6c809
Show file tree
Hide file tree
Showing 68 changed files with 2,378 additions and 1,771 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Most existing solutions were either too complex, too restrictive, or difficult t
- 🛠️ **Frappe CMS Integration:** Easily fetch data from your database and create dynamic pages.
- 🧑‍💻 **Scripting Capabilities:** Customize with client scripts, global scripts, and styles.
- 🚀 **One-Click Publishing:** Instantly share your creation with the world in a single click.
-**Performance Excellence:** Frappe Builder does not bloat web pages with unnecessary scripts hence pages built with Frappe Builder are highly performant, consistently scoring high on Google Lighthouse tests.
-**Performance Excellence:** Frappe Builder does not bloat web pages with unnecessary scripts hence pages are highly performant, consistently scoring high on Google Lighthouse tests.
- 🧰 **Production Ready**: [Frappe.io](https://frappe.io) built on Frappe Builder, stands as a testament to its reliability in delivering production-ready solutions.

### Under the Hood

Expand Down
20 changes: 20 additions & 0 deletions builder/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,23 @@ def update_page_folder(pages: list[str], folder_name: str) -> None:
frappe.throw("You do not have permission to update page folder.")
for page in pages:
frappe.db.set_value("Builder Page", page, "project_folder", folder_name, update_modified=False)


@frappe.whitelist()
def duplicate_page(page_name: str):
if not frappe.has_permission("Builder Page", ptype="write"):
frappe.throw("You do not have permission to duplicate a page.")
page = frappe.get_doc("Builder Page", page_name)
new_page = frappe.copy_doc(page)
del new_page.page_name
new_page.route = None
client_scripts = page.client_scripts
new_page.client_scripts = []
for script in client_scripts:
builder_script = frappe.get_doc("Builder Client Script", script.builder_script)
new_script = frappe.copy_doc(builder_script)
new_script.name = f"{builder_script.name}-copy"
new_script.insert(ignore_permissions=True)
new_page.append("client_scripts", {"builder_script": new_script.name})
new_page.insert()
return new_page
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-06-20 08:16:29.611058",
"modified": "2025-01-29 09:30:34.896956",
"modified_by": "Administrator",
"module": "Builder",
"name": "Builder Component",
Expand Down Expand Up @@ -78,5 +78,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "component_name"
"title_field": "component_name",
"track_changes": 1
}
2 changes: 1 addition & 1 deletion builder/builder/doctype/builder_page/builder_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ def get_tag(block, soup, data_key=None):
if data_key:
_key = f"{data_key}.{_key}"

item_key = f"key_{block.get('blockId')}"
item_key = f"key_{_key.replace('.', '__')}"
tag.append(f"{{% for {item_key} in {_key} %}}")
tag.append(get_tag(block.get("children")[0], soup, item_key))
tag.append("{% endfor %}")
Expand Down
19 changes: 18 additions & 1 deletion builder/builder/doctype/builder_page/test_builder_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,24 @@ def setUpClass(cls):
"page_title": "Test Page",
"published": 1,
"route": "/test-page",
"blocks": [{"element": "body", "children": [{"element": "h1", "innerHTML": "Hello World!"}]}],
"blocks": [
{
"element": "body",
"baseStyles": {"background": "red", "fontFamily": "Inter"},
"customAttributes": {"dir": "ltr"},
"children": [
{
"element": "h1",
"innerHTML": "Hello World!",
"baseStyles": {
"color": "blue",
"fontFamily": "Comic Sans MS",
"fontWeight": "500",
},
}
],
}
],
}
).insert(ignore_if_duplicate=True)
cls.page_with_dynamic_route = frappe.get_doc(
Expand Down
2 changes: 1 addition & 1 deletion frappe-ui
Submodule frappe-ui updated 55 files
+25 −0 .github/workflows/vitest.yml
+2 −0 docs/components/confirm-dialog.md
+0 −8 netlify.toml
+10 −9 package.json
+9 −1 src/components/ConfirmDialog.vue
+1 −2 src/components/DatePicker/DatePicker.vue
+1 −2 src/components/DatePicker/DateRangePicker.vue
+1 −2 src/components/DatePicker/DateTimePicker.vue
+43 −41 src/components/Dialog.vue
+1 −1 src/components/Dropdown.vue
+5 −1 src/components/FormControl.vue
+1 −1 src/components/ListView/ListGroupHeader.vue
+2 −2 src/components/ListView/ListHeaderItem.vue
+1 −1 src/components/ListView/ListRow.vue
+0 −0 src/components/ListView/ListView.story.md
+11 −12 src/components/ListView/ListView.story.vue
+7 −0 src/components/ListView/ListView.vue
+6 −6 src/components/Select.vue
+0 −15 src/components/Tabs.story.md
+0 −110 src/components/Tabs.vue
+82 −0 src/components/Tabs/TabList.vue
+17 −0 src/components/Tabs/TabPanel.vue
+97 −0 src/components/Tabs/Tabs.story.md
+34 −9 src/components/Tabs/Tabs.story.vue
+57 −0 src/components/Tabs/Tabs.vue
+7 −4 src/components/TextEditor/InsertImage.vue
+1 −0 src/components/TextEditor/InsertVideo.vue
+2 −0 src/components/TextInput.vue
+150 −0 src/data-fetching/docStore.ts
+113 −0 src/data-fetching/idbStore.ts
+6 −0 src/data-fetching/index.ts
+22 −0 src/data-fetching/useCall/types.ts
+210 −0 src/data-fetching/useCall/useCall.test.ts
+227 −0 src/data-fetching/useCall/useCall.ts
+119 −0 src/data-fetching/useDoc/useDoc.test.ts
+173 −0 src/data-fetching/useDoc/useDoc.ts
+84 −0 src/data-fetching/useDoctype/useDoctype.test.ts
+196 −0 src/data-fetching/useDoctype/useDoctype.ts
+100 −0 src/data-fetching/useFrappeFetch.ts
+47 −0 src/data-fetching/useList/listStore.ts
+49 −0 src/data-fetching/useList/types.ts
+215 −0 src/data-fetching/useList/useList.test.ts
+351 −0 src/data-fetching/useList/useList.ts
+57 −0 src/data-fetching/useNewDoc/useNewDoc.ts
+73 −0 src/data-fetching/utils.ts
+9 −1 src/index.js
+125 −0 src/mocks/handlers.ts
+4 −0 src/mocks/node.ts
+26 −0 src/mocks/utils.ts
+2 −1 src/utils/confirmDialog.js
+5 −2 tsconfig.json
+6 −1 tsconfig.node.json
+9 −0 vitest.config.ts
+14 −0 vitest.setup.ts
+473 −192 yarn.lock
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"ace-builds": "^1.22.0",
"autoprefixer": "^10.4.2",
"feather-icons": "^4.28.0",
"frappe-ui": "0.1.93",
"frappe-ui": "0.1.108",
"opentype.js": "^1.3.4",
"pinia": "^2.0.28",
"postcss": "^8.4.5",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/builder.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ declare interface ContextMenuOption {
label: string;
action: CallableFunction;
condition?: () => boolean;
disabled?: () => boolean;
}

declare interface ComponentData {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/AlertDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</template>

<script lang="ts" setup>
import { Dialog } from "frappe-ui";
import Dialog from "@/components/Controls/Dialog.vue";
import { onMounted, ref } from "vue";
const props = defineProps(["title", "message", "onClick"]);
Expand Down
10 changes: 3 additions & 7 deletions frontend/src/components/BackgroundHandler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
class="absolute left-2 top-[6px] z-10 h-4 w-4 rounded shadow-sm"
@click="togglePopover"
:class="{
'bg-gray-400 dark:bg-zinc-600': !backgroundURL,
'bg-surface-gray-4': !backgroundURL,
}"
:style="{
backgroundImage: backgroundURL ? `url(${backgroundURL})` : '',
Expand All @@ -31,7 +31,7 @@
<template #body>
<div class="rounded-lg bg-surface-white p-3 shadow-lg">
<div
class="image-preview group relative h-24 w-48 cursor-pointer overflow-hidden rounded bg-gray-200 dark:bg-zinc-700"
class="image-preview group relative h-24 w-48 cursor-pointer overflow-hidden rounded bg-surface-gray-3"
:style="{
backgroundImage: backgroundURL ? `url(${backgroundURL})` : '',
backgroundPosition: `center`,
Expand All @@ -53,11 +53,7 @@
'!grid': !backgroundURL,
'group-hover:grid': backgroundURL,
}">
<div
class="rounded bg-gray-200 p-2 text-xs text-gray-900 dark:bg-zinc-700 dark:text-zinc-200"
@click="openFileSelector">
Upload
</div>
<BuilderButton @click="openFileSelector">Upload</BuilderButton>
</div>
</template>
</FileUploader>
Expand Down
17 changes: 9 additions & 8 deletions frontend/src/components/BlockContextMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,6 @@ const contextMenuOptions: ContextMenuOption[] = [
return selectedBlocks.every((block: Block) => block.getParentBlock() === parentBlock);
},
},
{
label: "Save As Component",
action: () => (showNewComponentDialog.value = true),
condition: () => !block.value.isExtendedFromComponent(),
},
{
label: "Repeat Block",
action: () => {
Expand All @@ -166,7 +160,8 @@ const contextMenuOptions: ContextMenuOption[] = [
},
{
label: "Reset Overrides",
condition: () => block.value.hasOverrides(store.activeBreakpoint),
condition: () => store.activeBreakpoint !== "desktop",
disabled: () => !block.value?.hasOverrides(store.activeBreakpoint),
action: () => {
block.value.resetOverrides(store.activeBreakpoint);
},
Expand Down Expand Up @@ -216,6 +211,11 @@ const contextMenuOptions: ContextMenuOption[] = [
},
condition: () => !block.value.isExtendedFromComponent() && Boolean(window.is_developer_mode),
},
{
label: "Save As Component",
action: () => (showNewComponentDialog.value = true),
condition: () => !block.value.isExtendedFromComponent(),
},
{
label: "Detach Component",
action: () => {
Expand All @@ -230,12 +230,13 @@ const contextMenuOptions: ContextMenuOption[] = [
{
label: "Delete",
action: () => {
block.value.getParentBlock()?.removeChild(block.value);
store.activeCanvas?.removeBlock(block.value);
},
condition: () => {
return (
!block.value.isRoot() &&
!block.value.isChildOfComponentBlock() &&
block.value.isVisible() &&
Boolean(block.value.getParentBlock())
);
},
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/BlockEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const showPaddingHandler = computed(() => {
!props.editable &&
!blockController.multipleBlocksSelected() &&
!props.block.isSVG() &&
!props.block.isText()
(!props.block.isText() || (props.block.isLink() && props.block.hasChildren()))
);
});
Expand All @@ -107,7 +107,7 @@ const showMarginHandler = computed(() => {
!resizing.value &&
!props.editable &&
!blockController.multipleBlocksSelected() &&
!props.block.isText()
(!props.block.isText() || (props.block.isLink() && props.block.hasChildren()))
);
});
Expand Down Expand Up @@ -162,7 +162,7 @@ const getStyleClasses = computed(() => {
if (movable.value && !props.block.isRoot()) {
classes.push("cursor-grab");
}
if (Boolean(props.block.extendedFromComponent)) {
if (props.block.isExtendedFromComponent()) {
classes.push("ring-purple-400");
} else {
classes.push("ring-blue-400");
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/BlockLayers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<FeatherIcon
:name="isExpanded(element) ? 'chevron-down' : 'chevron-right'"
class="ml-[-18px] h-3 w-3 text-ink-gray-4"
v-if="element.children && element.children.length && !element.isRoot()"
v-if="element.children && element.children.length && !element.isRoot() && element.isVisible()"
@click.stop="toggleExpanded(element)" />
<FeatherIcon
:name="element.getIcon()"
Expand Down
13 changes: 6 additions & 7 deletions frontend/src/components/BlockPositionHandler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,16 @@
@update:modelValue="(value: string) => blockController.setStyle('left', value)" />
</div>
<div
class="grid-col-3 grid h-16 w-16 grid-rows-3 gap-1 self-center justify-self-center rounded bg-gray-50 p-2 dark:bg-zinc-800">
class="grid-col-3 grid h-16 w-16 grid-rows-3 gap-1 self-center justify-self-center rounded bg-surface-gray-2 p-2">
<div
class="col-span-3 row-start-1 h-2 w-[2px] self-center justify-self-center rounded bg-surface-gray-2"></div>
class="col-span-3 row-start-1 h-2 w-[2px] self-center justify-self-center rounded bg-surface-gray-4"></div>
<div
class="col-span-3 row-start-3 h-2 w-[2px] self-center justify-self-center rounded bg-surface-gray-2"></div>
class="col-span-3 row-start-3 h-2 w-[2px] self-center justify-self-center rounded bg-surface-gray-4"></div>
<div class="h-5 w-5 self-center justify-self-center rounded bg-gray-400 bg-surface-gray-4"></div>
<div
class="surface-grabg-surface-gray-2 h-5 w-5 self-center justify-self-center rounded bg-gray-400"></div>
class="col-span-1 col-start-1 row-start-2 h-[2px] w-2 self-center justify-self-center rounded bg-surface-gray-4"></div>
<div
class="col-span-1 col-start-1 row-start-2 h-[2px] w-2 self-center justify-self-center rounded bg-surface-gray-2"></div>
<div
class="col-span-1 col-start-3 row-start-2 h-[2px] w-2 self-center justify-self-center rounded bg-surface-gray-2"></div>
class="col-span-1 col-start-3 row-start-2 h-[2px] w-2 self-center justify-self-center rounded bg-surface-gray-4"></div>
</div>
<div class="col-span-1 col-start-3 w-16 self-center">
<BuilderInput
Expand Down
Loading

0 comments on commit 8d6c809

Please sign in to comment.